同源策略
由于浏览器的同源策略,如果两个页面的协议,端口(如果有指定)和域名都相同,则两个页面具有相同的源,只要有一者不同,就会造成跨域
jsonp
jsonp由两部分组成:回调函数和数据。回调函数是当响应到来时应该在页面中调用的函数。回调函数的名字一般是在请求中指定。而数据就是传入回调函数中的JSON数据。形式如下:
<script> var localHandle = function(data){ alert("返回的数据:" + data); } </script> <script src="http://remoteserver.com/remote.js?name=value&callback=localHandle"></script>remote.js代码如下:
localHandler({"result":"我是远程js带来的数据"}); 服务器根据请求里的callback=localHandle知道了本地的回调函数名称localHandle,查询字符串为name=value,然后服务器执行相对应的函数并返回数据给本地的localHandle回调函数。
建议动态的创建script来查询
<script> var localHandle = function(data){ alert("返回的数据:" + data); } // 提供jsonp服务的url地址(不管是什么类型的地址,最终生成的返回值都是一段javascript代码) var url = "http://remoteserver.com/remote.js?name=value&callback=localHandle"; // 创建script标签,设置其属性 var script = document.createElement('script'); script.setAttribute('src', url); // 把script标签加入head,此时调用开始 document.getElementsByTagName('head')[0].appendChild(script); </script>jsonp优点
简单易用,能够直接访问响应文本,支持浏览器和服务器之间的双向通信
jsonp缺点
- 安全性不足。借助JSONP有可能进行跨站请求伪造(CSRF)攻击,当一个恶意网站使用访问者的浏览器向服务器发送请求并进行数据变更时,被称为CSRF攻击。由于请求会携带cookie信息,服务器会认为是用户自己想要提交表单或者发送请求,而得到用户的一些隐私数据。
- 错误原因不易找。JSONP缺乏错误处理机制,如果脚本注入成功后,就会调用回调函数,但是注入失败后,没有任何提示。这就意味着,当JSONP遇到404、505或者其他服务器错误时,你是无法检测出错原因的。我们能够做的也只有超时,没有收到响应,便认为请求失败,执行对应的错误回调。
- 只能适用于get请求。只能使用GET请求就意味着很多限制,提交到服务器的数据量将受限于浏览器的最大URL长度。
jsonp封装
/** * JSONP请求工具 * @param url 请求的地址 * @param data 请求的参数 * @returns {Promise<any>} */ const request = ({url, data}) => { return new Promise((resolve, reject) => { // 处理传参成xx=yy&aa=bb的形式 const handleData = (data) => { const keys = Object.keys(data) const keysLen = keys.length return keys.reduce((pre, cur, index) => { const value = data[cur] const flag = index !== keysLen - 1 ? '&' : '' return `${pre}${cur}=${value}${flag}` }, '') } // 动态创建script标签 const script = document.createElement('script') // 接口返回的数据获取 window.jsonpCb = (res) => { document.body.removeChild(script) delete window.jsonpCb resolve(res) } script.src =
