实现一个JSONP

作者: 厂厂哥 | 来源:发表于2019-02-19 00:05 被阅读5次

同源策略

同源策略是一种约定,指的是协议、域名和端口三者相同,它是浏览器最核心也是最基本的安全功能。缺少这个功能,
就容易受到XSS、CSRF的攻击。
同源策略的限制内容:
(一)Cookies、LocalStrange、IndexedDB等存储性的内容。
(二)DOM节点。
(三)AJAX请求发送后,结果被浏览器拦截。

JSONP

原理

三个标签允许跨域:img标签、link标签、script标签,JSONP就是利用script的这个特性进行跨域。

实现步骤

(一)声明一个回调函数,其函数值作为参数值,要传递给跨域请求数据的服务器,函数的形式参数为服务器返回的数据。
(二)创建一个script标签,把那个跨域的API数据接口地址,赋值给script的src,还要在这个地址中向服务器传递该函数名。通常使用?传递参数
(三)服务器接受请求,对数据进行拼接处理。
(四)服务器通过HTTP协议把数据返回给客户端,客户端再调用之前的回调函数。

用于测试的服务端

//1、引入模块  使用的http服务协议是RFC2616  nodejs的作者已经写好了,直接引入就行
var http = require('http');
var querystring = require('querystring');
//引入文件读写模块fs
var fs = require('fs');
//2、创建服务器    函数的参数req是发送给服务器的请求,res是服务器的相应
var httpObj = http.createServer(function (req, res) {
  var qs = querystring.parse(req.url.split('?')[1]);
  res.writeHead(200, { 'Content-Type': 'application/json;charset=utf-8' });
  var data = "Monkey"
  var callback = qs.callback + '(' + JSON.stringify(data) + ')';
  res.end(callback);
});
//监听端口
httpObj.listen(3000);

JSONP的实现

首先实现一个最简单的JSOP;

function jsonp(url){
  const script=document.createElement("script");
  script.src=url;
  script.type="type/javascript";
  document.body.appendChild(script);
}

这个只是最基本的写法,要是想要使用需要定义全局的回调函数,这样是不可取的。
接下来,进行改进:

function jsonp({url,params,callback}){
  window[callback]=callback;
  const script=document.createElement("script");
  let arr=[];
  params={...params,callback};
  for(var key in params){
    arr.push(`${key}=${params[key]}`);
  }
  script.src = `${url}?${arrs.join('&')}`;
  script.type="type/javascript";
  document.body.appendChild(script);
}

这个函数改进了上面的不足,但是还有很多的不足:
(1)没有清楚生成的script标签。
(2)要写回调,写法麻烦。
下面使用es6的promise进行改进:

    function jsonp({ url, params, callback }) {
      return new Promise((resolve, reject) => {
        let script = document.createElement('script');
        window[callback] = (data) => {
          resolve(data);
          document.body.removeChild(script);//删除了script标签
        }
        params = { ...params, callback };
        let arrs = [];
        for (let key in params) {
          arrs.push(`${key}=${params[key]}`);
        }
        script.src = `${url}?${arrs.join('&')}`;
          script.type="type/javascript";
        document.body.appendChild(script);
      });
    }
    jsonp({
      url: 'http://localhost:3000/',
      params: { test: 'test' },
      callback: 'show'
    }).then((data) => {
      console.log(data);
    }).catch((e) => { console.log(e) })

上面已经通过es6实现了JSONP,但是是否觉得有什么不对劲的地方,没错,就是缺少了错误处理。
最后的改进:

    function jsonp({ url, params, callback }) {
      return new Promise((resolve, reject) => {
        let script = document.createElement('script');
        window[callback] =  (data) => {
          resolve(data);
          document.body.removeChild(script);
        }
        params = { ...params, callback }; 
        let arrs = [];
        for (let key in params) {
          arrs.push(`${key}=${params[key]}`);
        }
        script.src = `${url}?${arrs.join('&')}`;
        script.type="type/javascript";
        document.body.appendChild(script);
        script.onerror = () => {
          reject(new Error(`fetch ${url} failed`));
          document.body.removeChild(script);
        }
      });
    }
    jsonp({
      url: 'http://localhost:3001/',
      params: { test: 'test' },
      callback: 'show'
    }).then((data) => {
      console.log(data);
    }).catch((e) => { console.log(e) })

    jsonp({
      url: 'http://localhost:3000/',
      params: { test: 'test' },
      callback: 'show'
    }).then((data) => {
      console.log(data);
    }).catch((e) => { console.log(e) })

说在最后

小菜鸡大三下了,希望找实习了,有一起找实习的小伙伴私信我吧,一起努力吧。
最后不要脸的说一句:github求star("https://github.com/changchangge").

相关文章

  • ES6解决跨域

    实现一个jsonp函数,仅需要支持jsonp(url)一种调用方式即可(仅有url一个传参),例如: jsonp(...

  • 跨域方案

    JSONP JSON with padding 简称JSONP ,实现原理 通过动态 元素,指定src属性为一个跨...

  • day02-vuejs-vue-resource实现get, p

    vue-resource实现get, post, jsonp]请求: JSONP的实现原理: 由于浏览器的安全性限...

  • JSONP理解和实现

    JSONP的格式 JSONP 不支持 POST的原因 i、因为JSONP是通过创建script实现的 ii、动态创...

  • JSONP的历史方案和实现原理

    1. JSONP的实现原理 JSONP是通过动态创建script实现的。请求方:frank.com 的前端程序员(...

  • 遇到的面试题

    null instanceOf Object false jsonp跨域原理,优缺点,安全性因素 jsonp的实现...

  • 前端跨域请求原理及实践

    一、 跨域请求的含义 2.3 使用 标签原生实现 JSONP 经过上面的事件,你是不是觉得 JSONP 的实现和...

  • 前端跨域请求原理及实践

    一、 跨域请求的含义 2.3 使用 标签原生实现 JSONP 经过上面的事件,你是不是觉得 JSONP 的实现和...

  • 实现一个JSONP

    回调函数调用后需要将添加的script标签进行删除,并将函数置空

  • 实现一个JSONP

    同源策略 同源策略是一种约定,指的是协议、域名和端口三者相同,它是浏览器最核心也是最基本的安全功能。缺少这个功能,...

网友评论

    本文标题:实现一个JSONP

    本文链接:https://www.haomeiwen.com/subject/cbutyqtx.html