浏览器的同源策略不允许我们直接通过ajax call别的域名上的url,但是script,img标签却米有这个限制,jsonp便是利用了这一点,通过在页面上生成一个src为我们所要调用url的script标签,能拿到服务器返回的结果,当然这个只支持get请求,同样,服务器端也要能够接受我们所传递的参数。
下面是一个例子:
<script> function removeScript(scriptId) { const script = document.getElementById(scriptId); document.getElementsByTagName('head')[0].removeChild(script); } function clearFunction(functionName) { try { delete window[functionName]; } catch (e) { window[functionName] = undefined; } } function call(url) { return new Promise(function(resolve, reject) { var callbackFunction = 'callbackFunc' + Math.ceil(Math.random() * 100000000000000000); url += (url.indexOf('?') === -1) ? '?' : '&'; const jsonpScript = document.createElement('script'); jsonpScript.setAttribute('src', `${url}callback=${callbackFunction}`); scriptId = callbackFunction; jsonpScript.id = scriptId; document.getElementsByTagName('head')[0].appendChild(jsonpScript); window[callbackFunction] = function(data) { console.log('--------------------------------'); removeScript(scriptId); clearFunction(callbackFunction); resolve(data); } }); } //这里我后台用的sails,返回的类似于这样子:callbackFunc20461582336288720({"a":'aa','b':'bb'}) call("http://localhost:1337/test/test1").then(function(data) { console.log(data); }).catch(function(error) { console.log(error); }) </script>
这里用了Promise,只处理了正常resolve的,以后也可以加reject弄个超时处理之类,这里需要注意的是在完成方法的调用后,一定要记得将script remove掉,window上挂载的方法也要remove掉。