2017-04-07 200 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 
     } 
    } 
}