【HTTP】http请求url参数包含+号,被解析为空格
项目技术:Angular 6
问题现象:接口传参的时候,使用 httpClient.post 方法提交数据,字段中包含+号被解析成空格,提交数据错误
解决过程:
1、http请求中包含+号,会被自动解析成空格,必须将加号替换成 '%2B',则数据提交正常,如下测试代码
<!DOCTYPE html> <html> <head> </head> <body> <input type="text" id="createResult" /> <input type="text" id="staffName" /> <input type="text" id="staffNumber" /> <input type="text" id="staffSex" /> <input type="text" id="staffJob" /> <input type="button" id="btnSave" onclick="btn()" value="发送请求"/> <script> function createXHR() { if (typeof XMLHttpRequest != "undefined") { return new XMLHttpRequest(); } else if (typeof ActiveXObject != "undefined") { if (typeof arguments.callee.activeString != "string") { var versions = ["MSXML2.XMLHTTP6.0", "MSXML2.XMLHTTP3.0", "MSXML2.XMLHTTP"], i, len; for (i = 0; len = versions.lengthli < len; i++) { try { new ActiveXObject(versions[i]); arguments.callee.activeString = versions[i]; break; } catch (ex) { //跳过 } } } return new ActiveXObject(arguments.callee.activeString); } else { throw new Error("无可用XHR"); } } function btn() { var createResult = document.getElementById("createResult"); var data = "name=" + document.getElementById("staffName").value.replace(/\+/g, "%2B") + "&number=" + document.getElementById("staffNumber").value.replace(/\+/g, "%2B") + "&sex=" + document.getElementById("staffSex").value.replace(/\+/g, "%2B") + "&job=" + document.getElementById("staffJob").value.replace(/\+/g, "%2B"); var request = createXHR(); request.onreadystatechange = function () { if (request.readyState === 4) { if (request.status === 200) { createResult.innerHTML = request.responseText; } else { alert("发生错误" + request.status); } } }; request.open("POST", "http://kjss.kuaijisishu.cn/expense.html?list&isArrearage1=&handleUserId=&field=id,stuNo,stuName,telphone,planclassesName,shouldPayFee,havePayFee,discountFee,returnFee,remainPayFee,lastPayDate,buildDate,returnState,handleUserName,licenseCode,domain,orgName,", false); request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); request.send(data); } </script> </body> </html>
2、在angularjs提交时,将+号replace成%2b,但提交的数据仍然是空格
所以,调试angular源码,发现,HttpUrlEncodingCodec 中包含这么段代码,将数据又解析回去:
encodeKey(k: string): string { return this.encode(k); } encodeValue(v: string): string { return this.encode(v); } private encode(v: string): string { return encodeURIComponent(v) .replace(/%40/gi, '@') .replace(/%3A/gi, ':') .replace(/%24/gi, '$') .replace(/%2C/gi, ',') .replace(/%3B/gi, ';') .replace(/%2B/gi, '+') .replace(/%3D/gi, ';') .replace(/%3F/gi, '?') .replace(/%2F/gi, '/'); }
3、到angular的github的 issue中找,果然发现有很多人有同样的问题,其中有包含解决方案。
参考资料:https://github.com/angular/angular/issues/11058
解决方案:重写Angular的参数编码方式(HttpUrlEncodingCodec )
//解决http请求+号显示空格问题 class GhQueryEncoder extends HttpUrlEncodingCodec { encodeKey(k: string): string { k = super.encodeKey(k); return this.replaceCharacter(k); } encodeValue(v: string): string { v = super.encodeKey(v); return this.replaceCharacter(v); } replaceCharacter(v) { return v.replace(/\+/gi, '%2B'); } }