8

foreword

In the process of daily project development, cross-domain and how to solve cross-domain problems are topics that cannot be avoided by front-end and back-end development students. JSONP cross-domain is a classic solution to cross-domain problems.

💡Warm reminder: The full text of this article is 1921 words. The recommended reading time is 10min. Come on, old iron!

First, the same-origin policy and cross-domain

1.1 Same Origin Policy

1.1.1 What is homology

Two pages have the same source if 协议 , 域名 and 端口 are the same.<br>For example, the following table gives the relative Homologous detection on the http://www.test.com/index.html page:

20201031133802801.png

1.1.2 What is the Same Origin Policy

Same origin policy (English full name Same origin policy) is a security feature provided by browsers.

The concept officially given by MDN: the same-origin policy restricts how a document or script loaded from the same origin can interact with resources from another origin. This is an important security mechanism for isolating potentially malicious files.

Popular understanding: the browser stipulates that the JavaScript of the A website does not allow the interaction of resources with the non-same-origin website C, for example:

  • Unable to read Cookie , LocalStorage and IndexedDB of non-homologous web pages
  • Unable to access non-homologous web pages DOM
  • Unable to send AJAX request to non-same origin address

1.2 Cross-domain

1.2.1 What is cross domain

Homologous means that the two URLs 协议 , 域名 , --- b9e4587618e5819ff44a0fc717debffa 端口 are consistent, and vice versa.

The root cause of cross-origin: the browser's same-origin policy does not allow resource interaction between non-same-origin URLs.

Web page: http://www.test.com/index.html

Interface: http://www.api.com/userlist

1.2.2 Browser interception of cross-domain requests

img-blog.csdnimg.cn&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto.webp

Note: Browsers are allowed to initiate cross-domain requests, but the data returned by cross-domain requests will be intercepted by the browser and cannot be obtained by the page !

1.2.3 How to implement cross-domain data request

实现跨域数据请求方法有很多,比如JSONPCORSpostMessageWebsocketNginx反向代理window.name + iframe , document.domain + iframe , location.hash + iframe etc. The three main solutions are JSONP and CORS and Nginx reverse proxy.

  • JSONP : It appeared early and has good compatibility (compatible with lower versions of IE). It is a temporary solution that front-end programmers are forced to come up with in order to solve cross-domain problems. The disadvantage is that only GET POST are not supported.
  • CORS : It's a late comer, it's a W3C standard, and it's a fundamental solution for cross-domain AJAX requests. GET and POST requests are supported. The disadvantage is that it is not compatible with some lower version browsers.
  • Nginx reverse proxy : The same-origin policy does not limit the server and is the simplest cross-domain method. You only need to modify the configuration of nginx to solve the cross-domain problem, support all browsers, support session , do not need to modify any code, and will not affect server performance.

2. Overview of JSONP

JSONP (JSON with Padding) is a "usage pattern" of JSON that can be used to solve the problem of cross-domain data access by mainstream browsers.

2.1 The principle of JSONP

Define a callback function for obtaining cross-domain response data in advance, and initiate a request through the script tag that is not restricted by the same-origin policy (put the name of the callback function in the request's query parameter), then the server returns the execution of this callback function, and puts the data to be responded into the parameters of the callback function, the front-end script tag request to this callback function will be executed immediately after the execution , so the response data of the execution is obtained.

2.2 Advantages

  • It is not restricted by the same-origin policy as the XMLHttpRequest object implements the Ajax request
  • It's more compatible, works in older browsers, doesn't require XMLHttpRequest or ActiveX support
  • And after the request is completed, the result can be returned by calling callback

2.3 Disadvantages

  • It only supports GET request but not POST and other types of HTTP requests
  • It only supports cross-domain HTTP requests, and cannot solve the problem of how to make JavaScript calls between two pages of different domains

3. JSONP application process

  1. Set a script tag

     <script src="http://jsonp.js?callback=cb"></script>
    
    // 或
    
    let script = document.createElement('script');
    script.src = "http://jsonp.js?callback=cb";
    body.append(script)
  2. callback defines a function name, and the remote server passes the parameters by calling the specified function and passing in the parameters, and passes the function(response) back to the client
 router.get('/', function (req, res, next) {
    (() => {
        const data = {
            x: 10
        };
        let params = req.query;
        if (params.callback) {
            let callback = params.callback;
            console.log(params.callback);
            res.send(`${callback}(${JSON.stringify(data.x)})`);
        } else {
            res.send('err');
        }
    })();
});
  1. The client receives the returned JS script and starts parsing and executing function(response)

Fourth, JSONP implementation

3.1 Simple example:

A simple JSONP implementation is actually splicing URL , and then dynamically adding a script element to the header.

Front-end JSONP method example:

 function jsonp(req) {
    var script = document.createElement('script');
    var url = req.url + '?callback=' + req.callback.name;
    script.src = url;
    document.getElementsByTagName('head')[0].appendChild(script);
}

Front-end JS example:

 function hello(res){
    alert('hello ' + res.data);
}
jsonp({
    url : '',
    callback : hello 
});

Server side code:

 var http = require('http');
var urllib = require('url');

var port = 8080;
var data = {'data':'world'};

http.createServer(function(req,res){
    var params = urllib.parse(req.url,true);
    if(params.query.callback){
        console.log(params.query.callback);
        // jsonp
        var str = params.query.callback + '(' + JSON.stringify(data) + ')';
        res.end(str);
    } else {
        res.end();
    }
    
}).listen(port,function(){
    console.log('jsonp server is on');
});

3.2 Reliable JSONP instance:

 (function (global) {
    var id = 0,
        container = document.getElementsByTagName("head")[0];

    function jsonp(options) {
        if(!options || !options.url) return;

        var scriptNode = document.createElement("script"),
            data = options.data || {},
            url = options.url,
            callback = options.callback,
            fnName = "jsonp" + id++;

        // 添加回调函数
        data["callback"] = fnName;

        // 拼接url
        var params = [];
        for (var key in data) {
            params.push(encodeURIComponent(key) + "=" + encodeURIComponent(data[key]));
        }
        url = url.indexOf("?") > 0 ? (url + "&") : (url + "?");
        url += params.join("&");
        scriptNode.src = url;

        // 传递的是一个匿名的回调函数,要执行的话,暴露为一个全局方法
        global[fnName] = function (ret) {
            callback && callback(ret);
            container.removeChild(scriptNode);
            delete global[fnName];
        }

        // 出错处理
        scriptNode.onerror = function () {
            callback && callback({error:"error"});
            container.removeChild(scriptNode);
            global[fnName] && delete global[fnName];
        }

        scriptNode.type = "text/javascript";
        container.appendChild(scriptNode)
    }

    global.jsonp = jsonp;

})(this);

Example of use:

 jsonp({
    url : "www.example.com",
    data : {id : 1},
    callback : function (ret) {
        console.log(ret);
    }
});

Five, JSONP security issues

5.1 CSRF attack

The front-end constructs a malicious page, requests the JSONP interface, and collects sensitive information on the server. If the JSONP interface also involves some sensitive operations or information (such as login, delete, etc.), it is even less secure.

Solution : Verify the calling source of JSONP ( Referer ), and the server judges whether Referer is a whitelist, or deploy random Token for defense.

5.2 XSS Vulnerability

content-type XSS ,想象一下JSONP 就是你请求http://abc.com?callback=douniwan , 然后返回douniwan({ data }) ,那假如请求http://abc.com?callback=<script>alert(1)</script> If not, it will return <script>alert(1)</script>({ data }) , if it is not strictly defined Content-Type( Content-Type: application/json ) , directly as HTML parameter callback , is a naked XSS .

解决方法Content-Type: application/json ,然后严格过滤callback后的参数并且限制长度(进行字符转义, < &lt , > to &gt ), etc., the returned script content will be in text format, and the script will not be executed.

5.3 The server is hacked and a string of maliciously executed code is returned

The executed code can be forwarded to the server to verify the JSONP content, and then return the verification result.

refer to

JSONP security that front-ends also need to know about

Cross-domain and JSONP_Small Blog - CSDN Blog

Cross-domain resource sharing CORS detailed explanation - Ruan Yifeng's network log


云鱼
3.2k 声望528 粉丝

感谢阅读、浏览和关注!