背景:項目安全處理方面之一 ——對特殊字符進行編解碼(后端編碼,前端解碼)
特殊字符:
" %22
\ %5C
/ %2F
& %26
% %25
' %27
; %3B
[ %5B
] %5D
^ %5E
< %3C
> %3E
Note:均為英文下,中文下不考慮
問題:使用JSON.parse(decodeURIComponent(JSON.stringify(body)))報錯 ——Uncaught SyntaxError: Unexpected token / in JSON at position 150
原因:ECMA script注明json字符串中需要轉義的字符: " / \ b f n r t
思路:
1、JSON.stringify()之后替換特殊字符
2、decodeURIComponent()之后替換特殊字符
解決:
經驗證,特殊字符需要替換為“\特殊字符”,再使用JSON.parse()可以解決。
1、\必須最先替換,防止多余替換其他特殊字符之前的\;
2、"必須在JSON.stringify()之后替換,若在decodeURIComponent()之后替換,會將json結構屬性,和屬性名的"也替換;
3、\和b f n r t結合,JSON.parse()也會報錯,但單獨存在不會被編碼。
JSON.parse(decodeURIComponent(
JSON.stringify(body).replace(/%5C/g,'%5C%5C')
.replace(/%22/g,"%5C%22")
.replace(/%2F/g,'%5C%2F')
.replace(/%08/g,'%5Cb')
.replace(/%0C/g,'%5Cf')
.replace(/%0A/g,'%5Cn')
.replace(/%0D/g,'%5Cr')
.replace(/%09/g,'%5Ct')));
注:
body =
{
"code": 0,
"message": "success",
"data": {
"offeringBasicList": [{
"offeringId": 2019000167,
"classifyId": 1000000009,
"classifyName": "IOT",
"offeringCode": "%3B%3C%3E%27%22%2F%5C%40%23%24%25%5E%26*%28%29%5B%5Dabcd",
"offeringName": "%3C%3E%27%22%2F%5C%40%23%24%25%5E%26*%28%29%5B%5Dabcd",
"offeringShortName": "%3C%3E%27%22%2F%5C%40%23%24%25%5E%26*%28%29%5B%5Dabcd",
"offeringDesc": "%3C%3E%27%22%2F%5C%40%23%24%25%5E%26*%28%29%5B%5Dabcd",
"isBundled": "N",
"ownerPartyRole": "CA",
"ownerPartyId": "0ff08435-aa1b-49d5-9780-5384d4989c9e",
"releasePartyRole": null,
"releasePartyId": null,
"isPrimary": "Y",
"maxNum": null,
"minNum": null,
"beId": "101",
"orgId": null,
"createdBy": "0ff08435-aa1b-49d5-9780-5384d4989c9e",
"createdTime": 1526623849854,
"updatedBy": "0ff08435-aa1b-49d5-9780-5384d4989c9e",
"updatedTime": 1526623849854,
"thumbnailName": null,
"thumbnailDesc": null,
"thumbnailUrl": null,
"busiModeType": null,
"status": {
"key": "DRA",
"value": "Draft"
},
"ownerType": {
"key": "S",
"value": "Subscriber"
}
}],
"pageInfo": {
"beginRowNumber": 0,
"sortField": "created_time",
"totalRecord": 1
}
}
}
擴展:
1、URI標准不允許使用保留字符,如/,解決:
encodeURIComponent() 編碼
decodeURIComponent() 解碼
既可編碼保留字符,又可編碼多字節字符
2、decodeURIComponent()解碼包含'%'的字符串時,若%與之后的字符無法轉義為正常字符串會報錯,eg:'90%';
