標籤:

編碼表單數據時為什麼要將%20替換為+?

《JavaScript權威指南》中p495頁有如下代碼

function encodeFormData(data){
if(!data) return "";
var pairs = [];
for(var name in data){
if(!data.hasOwnProperty(name)) continue;
if(typeof data[name] === "function") continue;
var value = data[name].toString();
name = encodeURIComponent(name.replace("%20","+"))
value = encodeURIComponent(value.replace("%20","+"))
pairs.push(name + "=" + value);
}
return paris.join("")
}
function getData(url,data,callback){
var request = new XMLHttpRequest()
request.open("GET",url+"?"+encodeFormData(data))
request.onreadystatechange = function(){
if(request.readyState === 4 callback) callback(request)
}
request.send(null);
}

其中為什麼要做這樣的操作 name.replace("%20","+"),如果不替換,哪些數據可能讓應用掛掉?


這代碼是錯誤的,很可能你的版本有問題。

我查了手頭的犀牛書第五版中文版,代碼並不是這個樣子的。

實際正確的代碼是 encodeURIComponent(name).replace(/%20/g,"+")

這代碼的用途是把編碼為 %20 的空格替換為 +,因為由於歷史原因,表單提交的 x-www-form-urlencoded 格式要求空格編碼為 + 。但 encodeURIComponent 是遵照後來的標準編碼為 %20 的。


咳,盡信書則不如無書,在看書的過程中要時刻保持懷疑的心。

name = encodeURIComponent(name.replace("%20","+"))
value = encodeURIComponent(value.replace("%20","+"))

無論如何,這兩行是不對的,想一想為什麼

========== 思考分割線

首先假如想把編碼後的 percentage encoding string 中的 %20 替換成 + ,應該這麼寫

name = encodeURIComponent(name).replace("%20","+")
value = encodeURIComponent(value).replace("%20","+")

先編碼,後替換

其次,字元串替換假如需要全部替換的話,要用正則表達式

name = encodeURIComponent(name).replace(/%20/g,"+")
value = encodeURIComponent(value).replace(/%20/g,"+")

========== 代碼分割線

那麼為什麼要把 %20 替換成 + 呢?

按照 RFC3986 ,空格編碼後是 %20

For example, "%20" is the percent-encoding for the binary octet "00100000" (ABNF: %x20), which in US-ASCII corresponds to the space character (SP).

RFC 3986 - Uniform Resource Identifier (URI): Generic Syntax

但按照 HTML 標準,application/x-www-form-urlencoded 對空格是這樣處理的。

If the byte is 0x20 (U+0020 SPACE if interpreted as ASCII)

Replace the byte with a single 0x2B byte (U+002B PLUS SIGN character (+) if interpreted as ASCII).

https://html.spec.whatwg.org/multipage/forms.html#application/x-www-form-urlencoded-encoding-algorithm


沒有碰到過類似的轉碼問題,具體的原因不清楚,只能給個提示,在規範文檔中對於application/x-www-form-urlencoded編碼的解碼有如下規範:

To decode application/x-www-form-urlencoded payloads, the following algorithm should be used. ....

4.2 Replace any "+" (U+002B) characters in name and value with U+0020 SPACE characters.

http://www.w3.org/TR/html5/forms.html#application/x-www-form-urlencoded-encoding-algorithm

可能因為該規則,所以在encode之前需要replace替換空格為+。

當然題主給出的例子中使用的是GET,是否和上述規範中描述的編碼規則有關我就不是很明白了。


推薦閱讀:

【SEO學習之路】網址URL如何定義SEO效果最優?
網址後面用?/&等符號引導的語句有什麼功能?

TAG:JavaScript | URL |