共计 2038 个字符,预计需要花费 6 分钟才能阅读完成。
问题场景
jquery ajax,非 jsonp 申请,post 数据中 json 蕴含多个问号,比方“{“a”:“aa??”}”。
申请时前端报错,因为 jsonp 的参数加到了 post 数据中的?? 地位,就无奈通过 url 传入了。
报错信息(生产环境)
"parsererror" SyntaxError: Unexpected token ':'
at eval (<anonymous>)
at eval (jquery.js:339)
at Function.globalEval (jquery.js:340)
at text script (jquery.js:9773)
at ajaxConvert (jquery.js:8843)
at done (jquery.js:9260)
at XMLHttpRequest.callback (jquery.js:9720) "{}"
或者(开发环境)
"parsererror" Error: jQuery111009581711862361235_1597629221274 was not called
at Function.error (jquery.js?1157:248)
at s.converters.script json (jquery.js?1157:9893)
at ajaxConvert (jquery.js?1157:8843)
at done (jquery.js?1157:9260)
at HTMLScriptElement.script.onload.script.onreadystatechange (jquery.js?1157:9831) "{}"
或者(后盾接收数据)
前端发送的含 ??
的字符变成相似 jQuery183554546_6546423242342
模式的字符。
问题起因
咱们找到 jquery 的这段代码
// Detect, normalize options and install callbacks for jsonp requests
jQuery.ajaxPrefilter("json jsonp", function( s, originalSettings, jqXHR) {
var callbackName, overwritten, responseContainer,
jsonProp = s.jsonp !== false && (rjsonp.test( s.url) ?
"url" :
typeof s.data === "string" && !(s.contentType || "").indexOf("application/x-www-form-urlencoded") && rjsonp.test(s.data) &&"data"
);
看到如果 data 中存在?? 这种非凡写法,rjsonp.test(s.data) 返回 true,最终将 ”data” 赋值给 jsonProp。
而 data 中不存在?? 就会给 jsonProp 赋值为 false。
如果 jsonProp=“data”
那么会走到这段代码外面
// Handle iff the expected data type is "jsonp" or we have a parameter to set
if (jsonProp || s.dataTypes[ 0] === "jsonp" ) {
// Get callback name, remembering preexisting value associated with it
callbackName = s.jsonpCallback = jQuery.isFunction(s.jsonpCallback) ?
s.jsonpCallback() :
s.jsonpCallback;
// Insert callback into url or form data
if (jsonProp) {s[ jsonProp] = s[jsonProp].replace(rjsonp, "$1" + callbackName);
} else if (s.jsonp !== false) {s.url += ( rquery.test( s.url) ? "&" : "?" ) + s.jsonp + "=" + callbackName;
}
因为这行代码 s[jsonProp] = s[jsonProp].replace(rjsonp,“$1”+ callbackName);
最终 data 中的?? 会被替换为 callbackName,能够监听发现这个异常现象。
替换了这里就不会走上面的 s.url 的惯例 jsonp 参数赋值到 url 的解决了,所以导致异样的产生。
解决办法
让非凡 data 的 jsonProp=false,咱们从 jsonProp = s.jsonp !== false 这块动手,调用 ajax 时:
$.ajax 传参时 jsonp: false 赋值,这样 jsonProp 间接赋值为 false,不走正则检测,就不会出问题了。
那么如果跨域怎么办呢?
这个能够采纳服务端加跨域 header 解决。
参考:https://blog.csdn.net/whq12789/article/details/108050349