前端跨域方法 手写jsonp

什么是跨域

  • 浏览器同域策略要求协议、域名、 端口,都同样,只要一种不知足都属于跨域。

跨域有哪一些问题

一、没法获取非同源的cookie、localStorge,sensionStorge, indexedDB,ajax

二、 iframe 页面没法获取express

三、 没法发送ajax,fetch 请求,浏览器拒绝,须要服务端支持跨域设置CORS:json

  • 服务端设置响应头容许来源:
"Access-Control-Allow-Origin", "*"
复制代码
  • 服务端设置响应头容许cookie: 服务端 设置Access-Control-Allow-Credentials为true, XMLHttpRequest的withCredentials为true,跨域容许cookie发送
response.setHeader("Access-Control-Allow-Origin", "*");
复制代码
  • 服务端设置响应头容许methods:
response.setHeader("Access-Control-Allow-Methods", "*");
复制代码
  • 服务端设置容许响应头暴露:
response.setHeader("Access-Control-Expose-Headers", "*");
复制代码
  • 服务端设置请求的存储时间
response.setHeader("Access-Control-Max-Age", "3600");
复制代码

js常见的跨域方式:(未完)

一、经过jsonp 跨域

  • JSONP(JSON with Padding)是数据格式 JSON 的一种“使用模式”,可让网页从别的网域要数据。
  • 根据 XmlHttpRequest 对象受到同源策略的影响,而利用 <script> 元素的这个开放策略,网页能够获得从其余来源动态产生的JSON数据,而这种使用模式就是所谓的 JSONP。
  • 用JSONP抓到的数据并非JSON,而是任意的JavaScript,用 JavaScript解释器运行而不是用JSON解析器解析。
  • 全部,经过Chrome查看全部JSONP发送的Get请求都是js类型,而非 XHR

缺点

  • 只能使用Get请求
  • 不能注册 success、error 等事件监听函数,不能很容易的肯定 JSONP 请求是否失败
  • JSONP 是从其余域中加载代码执行,容易受到xss跨站请求伪造的攻击.

步骤:

  • 1.将传入的data数据转化为url字符串形式
  • 2.处理url中的回调函数
  • 3.建立一个script标签并插入到页面中
  • 4.挂载回调函数

jsonp 代码实现

function encodeParam(url, obj) {
     // 1.将传入的data数据转化为url字符串形式
     // {id:1,name:'jack'} => id=1&name=jack
     const dataString = url.indexof('?') ? '?' : '&';
     for(let key in data) {
       dataString += `${key}=${(data[key] !== undefinded ? data[key] : '' }`
     }
     return dataString;
  }
  const jsonp = function (url, data, callback) {
  //promise 返回 new Promise((resolve, reject)=>{...callback(data)-->resolve(data)...})
      let dataString = encodeParam(url, data);
      // 处理url 中的回调函数
      const cbfnName = `my_json_cb_${Math.ramdom().toString().repalce('.', '')}`;
      
      dataString += `callback=${cbfnName}`;
      
      // 3.建立一个script标签并插入到页面
      
      const scriptEle = document.createElement('script');
      scriptEle.src = `${url}${dataString}`
      
      // 四、挂载回调函数
      
      window[cbfnName] = function(data) {
        callback(data); 
        // 处理完回调函数的数据以后,删除jsonp的script标
        document.body.removeChild(scriptEle);
      }
      document.body.appendChild(scriptEle);    
  }
复制代码

服务端代码

let express = require('express');
let app = express();
app.get('/student', function(req, res) {
  let {...callback...} = res.query;
  res.end(`${callback}(data)`)
})
复制代码
相关文章
相关标签/搜索