在類(lèi)unix中,是\n (0x0A)。以為沒(méi)有什么大的問(wèn)題,沒(méi)想到,這次開(kāi)發(fā)一個(gè)小程序,卻讓我對(duì)這個(gè)問(wèn)題大為頭痛。
首先發(fā)現(xiàn)這個(gè)問(wèn)題是這樣的:
我的這個(gè)程序采用的是Extjs+php的方式,通過(guò)ajax進(jìn)行通訊。其中有個(gè)頁(yè)面,如圖:
兩個(gè)文本框,一個(gè)text,一個(gè)textarea,當(dāng)textarea中含有回車(chē)換行的時(shí)候,會(huì)出現(xiàn)腳本錯(cuò)誤。后面發(fā)現(xiàn)是因?yàn)槿绻?wù)器端返回的字符串換行了,會(huì)造成js解析出現(xiàn)錯(cuò)誤,可見(jiàn)js在解析json數(shù)據(jù)時(shí)候的語(yǔ)法還是和在本地定義的字符串變量的語(yǔ)法一致的。一個(gè)字符串不能多行,有回車(chē)換行的時(shí)候需要轉(zhuǎn)義符號(hào):\n (\r\n)。
不過(guò)這個(gè)并不是我要說(shuō)明的問(wèn)題,我要說(shuō)明的問(wèn)題是,當(dāng)我在解決這個(gè)問(wèn)題的時(shí)候,抓包分析的時(shí)候,發(fā)現(xiàn)一個(gè)有趣的現(xiàn)象,就是發(fā)現(xiàn)瀏覽器發(fā)送到服務(wù)器對(duì)回車(chē)換行的編碼不一致。
例如上圖中的字符串在通過(guò)extjs中的
復(fù)制代碼 代碼如下:
Ext.Ajax.request({
url:'CatMan.php',
form:this.FORM_NAME,
scope:this,
callback:function(o,s,r){
var retObj=Ext.decode(r.responseText);
if(retObj.success){
alert('保存成功!');
}
}
});
進(jìn)行保存時(shí)候,發(fā)現(xiàn)發(fā)送到服務(wù)器的編碼是這樣的:
catdesc=%E6%9E%97%0A%0A%E5%B0%910A%0A%0Aa%E5%8D%8E
注意其中的紅色標(biāo)記的%0A,這是\n的編碼。\r的編碼竟然不見(jiàn)了。
然后我如果采用form submit直接提交,卻發(fā)現(xiàn)編碼是:
%E6%9E%97%0D%0A%0D%0A%E5%B0%91%0D%0A%0D%0A%0D%0Aa%E5%8D%8E
發(fā)現(xiàn)\r(%0D)的編碼是在的。
(以上為在IE9中測(cè)試結(jié)果。)
難道是ExtJs的問(wèn)題?
如果分析Extjs的源代碼,找到取form值得地方。如下:
復(fù)制代碼 代碼如下:
serializeForm : function(form) {
debugger
var fElements = form.elements || (document.forms[form] || Ext.getDom(form)).elements,
hasSubmit = false,
encoder = encodeURIComponent,
name,
data = '',
type,
hasValue;
Ext.each(fElements, function(element){
name = element.name;
type = element.type;
if (!element.disabled name) {
if (/select-(one|multiple)/i.test(type)) {
Ext.each(element.options, function(opt){
if (opt.selected) {
hasValue = opt.hasAttribute ? opt.hasAttribute('value') : opt.getAttributeNode('value').specified;
data += String.format("{0}={1}", encoder(name), encoder(hasValue ? opt.value : opt.text));
}
});
} else if (!(/file|undefined|reset|button/i.test(type))) {
if (!(/radio|checkbox/i.test(type) !element.checked) !(type == 'submit' hasSubmit)) {
data += encoder(name) + '=' + encoder(element.value) + '';
hasSubmit = /submit/i.test(type);
}
}
}
});
return data.substr(0, data.length - 1);
},
可以發(fā)現(xiàn)extjs采用的是js中的encodeURIComponent函數(shù)進(jìn)行值的編碼。
難道是encodeURIComponent的問(wèn)題?
搜索網(wǎng)絡(luò),發(fā)現(xiàn)一篇博文中提到這個(gè)問(wèn)題,見(jiàn)http://www.yeahxj.com/2011/11/07/enter-code-for-all-browser/ (回車(chē)符 \r\n 在各個(gè)瀏覽器中無(wú)恥的表現(xiàn))
于是我在ie6,ie8,ie9中分別進(jìn)行了測(cè)試,發(fā)現(xiàn)果然存在這個(gè)問(wèn)題。
總結(jié):
這個(gè)問(wèn)題雖然小,但是在某些場(chǎng)合卻會(huì)讓人和頭痛,這也是搞計(jì)算機(jī)程序設(shè)計(jì)人員的悲哀,大量的不兼容,造成很多程序出現(xiàn)各種各樣奇怪的問(wèn)題。例如這個(gè)小問(wèn)題可能造成一個(gè)結(jié)果,例如,我這個(gè)程序,需要在前臺(tái)顯示內(nèi)容的時(shí)候保留回車(chē)換行。這種一般有兩種處理方法,一種是采用pre>標(biāo)簽,但是這個(gè)標(biāo)簽用起來(lái)很不方便的,嘗試發(fā)現(xiàn)格式變化不太好控制。另外一種方法就是將回車(chē)換行變?yōu)閎r />標(biāo)記。我就是采用的這種方法,剛開(kāi)始我寫(xiě)的正規(guī)表達(dá)式是/\r\n/,結(jié)果發(fā)現(xiàn)什么都沒(méi)匹配到,后面我就改成/[\r\n]/但是這種造成的問(wèn)題就是在ie6,7,8中將會(huì)多出一行來(lái)。最后為了統(tǒng)一處理,我改為先替換/\r\n/組合,然后再替換/\n/。問(wèn)題得到解決。
** 本人原創(chuàng)文章,轉(zhuǎn)摘請(qǐng)保留本段內(nèi)容,萬(wàn)分感謝!
** microdreamsoft(Lin Shaohua):
** 由于本人水平有限,歡迎各位高手指正。
您可能感興趣的文章:- 通過(guò)Java正則表達(dá)式去掉SQL代碼中回車(chē)換行和多余空格
- windows 中 \r\n 區(qū)別于 類(lèi)unix中的\n 疑問(wèn)理解(crlf回車(chē)換行)
- PHP 清除HTML代碼、空格、回車(chē)換行符的函數(shù)
- 把textarea中字符串里含有的回車(chē)換行替換成lt;brgt;的javascript代碼
- Js 回車(chē)換行處理的辦法及replace方法應(yīng)用