2017-04-07 75 views
1

假设我有一个名为urlslist的表单中的textarea,用户将在其中输入一个url列表,每行一个。我通过ajax处理提交,其查询如下。防止在表单中双重提交数据

$(function() { 
    $("#urlslist").submit(function(e) { 

     //prevent Default functionality 
     e.preventDefault(); 

     //get the action-url of the form 
     var actionurl = e.currentTarget.action; 

     //do your own request an handle the results 
     $.ajax({ 
      url: actionurl, 
      type: 'post', 
      dataType: 'json', 
      data: $("#urlslist").serialize(), 
      success: function(data) { 
       //put the result in another textarea here 
      } 
     }); 

    }); 

}); 

然后,我在另一个textarea中显示我的处理结果(即每个输入的另一个url)。它运行良好,但我想改进它,以便旧的URL不会通过ajax提交到服务器,同时不会清除任何textareas。

编辑1

我想我需要用一个例子来证明这一点。

假设urlslist textarea的包含一个url.I点击提交,我得到一个result.Now我添加的urlslist另一个网址,然后点击提交again.Now会出现在后request.How 2个URL可以我确保只发送新的网址。

+0

你想阻止发射,而第一个请求“的道路上”第二个请求?如果不是,你能解释一下“旧网址”的含义吗? – dimlucas

+0

禁用您的提交按钮,一旦点击并在获得响应或错误后再次启用 –

+0

@dimlucas检查我的编辑 – user2650277

回答

1

使用Do something only once lib从Mozilla的:

function executeOnce() { 
    var argc = arguments.length, 
    bImplGlob = typeof arguments[argc - 1] === "string"; 
    if (bImplGlob) { 
    argc++; 
    } 
    if (argc < 3) { 
    throw new TypeError("executeOnce - not enough arguments"); 
    } 
    var fExec = arguments[0], 
    sKey = arguments[argc - 2]; 
    if (typeof fExec !== "function") { 
    throw new TypeError("executeOnce - first argument must be a function"); 
    } 
    if (!sKey || /^(?:expires|max\-age|path|domain|secure)$/i.test(sKey)) { 
    throw new TypeError("executeOnce - invalid identifier"); 
    } 
    if (decodeURIComponent(document.cookie.replace(new RegExp("(?:(?:^|.*;)\\s*" + encodeURIComponent(sKey).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=\\s*([^;]*).*$)|^.*$"), "$1")) === "1") { 
    return false; 
    } 
    fExec.apply(argc > 3 ? arguments[1] : null, argc > 4 ? Array.prototype.slice.call(arguments, 2, argc - 2) : []); 
    document.cookie = encodeURIComponent(sKey) + "=1; expires=Fri, 31 Dec 9999 23:59:59 GMT" + (bImplGlob || !arguments[argc - 1] ? "; path=/" : ""); 
    return true; 
} 

您可以进行以下操作:

 // some custom helper 
String.prototype.s2b64 = function() { // make base64 from string 
    return window.btoa(unescape(encodeURIComponent(this))); 
} 
String.prototype.replaceArray = function(find, replace) { // replace by array 
    var replaceString = this; 
    for (var i = 0; i < find.length; i++) { 
    replaceString = replaceString.replace(find[i], replace[i]); 
    } 
    return replaceString; 
}; 
    // here we start : 
    var output = []; 
    $.each($("#urlslist textarea").first().val().split(/\n/), function(index, value) { 
    alert(index + ": " + value); 
    if (value != '') 
     executeOnce(function(v) { 
     output.push(value); 
     }, null, value, 'urldone_' + value.s2b64().replaceArray(
     ["expires", "path", "domain", "secure"], 
     ["e_xpires", "p_ath", "d_omain", "s_ecure"]) + ''); 
    }); 

    alert(output); 

有些部分可能看起来有点古怪,但它是所有关于牛市防止手动setCookie(如使用B64和搜索&取代,如果我们真的很倒霉并随机从b64输出中获取cookie关键字)

如果要删除所有保存的值,请在此处是代码:

var cookieNames = document.cookie.split(/=[^;]*(?:;\s*|$)/); 

    // Remove any that match the pattern 
    for (var i = 0; i < cookieNames.length; i++) { 
    if (/^urldone_/.test(cookieNames[i])) { 
     document.cookie = cookieNames[i] + '=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/'; 
    } 
    } 

JSfiddle

这是一个基于cookie的答案(由浏览器,刷新&重启证明)。

+0

它很好用,但是你能否更新你的答案来重置“只做一次事情” – user2650277

+0

@ user2650277你想要一个全局重置或一个关键(url)的关键之一?顺便说一句,我会更新我的功能,就好像你尝试一样,'expires | max \ -age | path | domain | secure'不是url/cookie关键字的有效部分。一个base64_encore应该把戏;) – Blag

+0

我正在看一个全球重置在这里......说用户删除结果textarea中的所有网址,我需要重置它 – user2650277

0

这里是工作示例开发形式此链接http://jsfiddle.net/userdude/2hgnZ/

$('form#id').submit(function(e){ 
    var form = $(this); 
form.children('input[type=submit]').attr('disabled', 'disabled'); 
// this is just for demonstration 
e.preventDefault(); 
$.ajax({ 
    url: ' http://fiddle.jshell.net/_display/', 
    type: 'get', 
    success: function(data) { 
    alert(data); 
    form.children('input[type=submit]').removeAttr('disabled'); 
    } 
}); 
return false; 
}); 
+0

读我编辑..... – user2650277

0
var map = [] 
     map['www.google.com'] = 'www.google.com'; 
     var urls = ['www.google.com', 'www.yahoo.com']; //this is form text area 
     for (var i = 0; i< urls.length; i++) { 
      if (map[urls[i]] !== urls[i]) { 
      console.log('post ' +); 
      map[urls[i]] = urls[i]; 
      } else { 
      console.log('don not post ' + urls[i]); 
      } 
     } 

看了上面的控制台代码,你可以得到一些想法 这里我一直
步骤1)VAR地图= []全球
步骤2)地图[ 'www.google.com'] = 'www.google.com';这一行演示已发布
步骤3)通过var url进行循环,这是你的文本区域
步骤4)if(map [urls [i]]!urls [i])检查当前已发布的链接是否发布别的不张贴

+0

是否可以继续重新加载 – user2650277

+0

不是,你从文档准备好的服务器上填充地图 –

0

我的建议是使用.one()方法。

的。一()方法是相同的。对(),所不同的是对于给定的元件和事件类型处理程序是其第一次调用后未结合的。http://api.jquery.com/one/

$("form").one('submit',function(e) { 

    //prevent Default functionality 
    e.preventDefault(); 

    //save current element to var for speed 
    var self = $(this); 

    //do your own request an handle the results 
    $.ajax({ 
     url: self.attr('action'), 
     type: self.attr('method'), 
     dataType: 'json', 
     data: $("#urlslist").serialize(), 
     success: function(data) { 
      //put the result in another textarea here 
     } 
    }); 

}); 

编辑:

至于重复,你需要与你的服务器双面(动作)脚本来检查对数据库以控制这种以确保每一个新的网址是独一无二的。你使用什么语言后端?

PHP

$con = //database connection 
if(isset($_POST['urlslist'] && $_POST['urlslist'] != '') { 
    $urls = explode("\n",$_POST['urlslist']); 
    foreach($urls as $url) { 
     if($exists = mysqli_query($con,"SELECT * FROM urls_table WHERE url = '$url'")) { 
      // run update or ignore 
     } else { 
      // insert into db 
     } 
    } 
}