项目技术: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');
}
}
05-27 03:04