吃透JSONP

注:文中代码均来自 方应杭github

实现

//前端jasonp实现
function jsonp(url) {
  return new Promise((resolve, reject) => {
    const random = "frankJSONPCallbackName" + Math.random();
    window[random] = data => {
      resolve(data);
    };
    const script = document.createElement("script");
    script.src = `${url}?callback=${random}`;
    script.onload = () => {
      script.remove();
    };
    script.onerror = () => {
      reject();
    };
    document.body.appendChild(script);
  });
}

jsonp("http://qq.com:8888/friends.js").then(data => {
  console.log(data);
});
//后端nodejs相关代码
 else if (path === "/friends.js") {
    if (request.headers["referer"].indexOf("http://frank.com:9999") === 0) {
      response.statusCode = 200;
      response.setHeader("Content-Type", "text/javascript;charset=utf-8");
      const string = `window['{{xxx}}']({{data}}) `
      const data = fs.readFileSync("./public/friends.js").toString();
      const string2 = string.replace("{{data}}", data).replace('{{xxx}}', query.callback);
      response.write(string2);
      response.end();
    } else {
      response.statusCode = 404;
      response.end();
    }
  }
//friends.js
{
  "name":1,
  "sex":2
}

代码解释

  1. callback
    (1) 前端每次发起jsonp请求随机生成一个全局函数,将函数名以 ? callback=函数名 的方式传递给后端,后端将callback参数替换到
    **window[’{{xxx}}’]({{data}})**中的‘{{xxx}}’部分。将friends.js中的数据替换到{{data}}部分
    (2) 前端收到响应后,将响应作为一个script脚本执行,即执行如下代码
    window[函数名](数据)
    
    显然,这段代码会调用之前生成的全局监听函数,并将friends.js中的数据当作参数传入。
    (3) 可以看出,前端设置的callback函数,必须通过后端的配合来调用,否则web世界没有安全可言。
  2. 怎么限制允许访问的源?
     if (request.headers["referer"].indexOf("http://frank.com:9999") === 0)
    
    服务器端的如下代码限制了只有http://frank.com:9999源的请求会被允许
  3. jsonp的关键
    jsonp的实现,关键在于通过动态添加script脚本,设置其src属性,发起可以绕过同源策略限制的请求
  4. JSONP的适用场景
    在不支持CORS的设备上发起跨域请求
  5. JSONP的缺点
    (1) 只支持GET请求
    (2) 对请求状态的支持非常有限,只有响应数据,没有状态码,没有错误信息
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值