跨域请求的方式及原理

跨域请求的含义

一般的,只要网站的 协议名protocol、 主机host、 端口号port 这三个中的任意一个不同,网站间的数据请求与传输便构成了跨域调用

  • 利用 JSONP 实现跨域调用

  • // 服务器 3000 上的请求页面
    function jsonpCallback(data) {
        console.log("jsonpCallback: " + data.name)
    }
    $("#submit").click(function() {
        var data = {
            name: $("#name").val(),
            id: $("#id").val()
        };
        $.ajax({
            url: 'http://localhost:3001/ajax/deal',
            data: data,
            dataType: 'jsonp',
            cache: false,
            timeout: 5000,
            // jsonp 字段含义为服务器通过什么字段获取回调函数的名称
            jsonp: 'callback',
            // 声明本地回调函数的名称,jquery 默认随机生成一个函数名称
            jsonpCallback: 'jsonpCallback',
            success: function(data) {
                console.log("ajax success callback: " + data.name)
            },
            error: function(jqXHR, textStatus, errorThrown) {
                console.log(textStatus + ' ' + errorThrown);
            }
        });
    });
    
    // 服务器 3001 上对应的处理函数
    app.get('/ajax/deal', function(req, res) {
        console.log("server accept: ", req.query.name, req.query.id)
        var data = "{" + "name:'" + req.query.name + " - server 3001 process'," + "id:'" + req.query.id + " - server 3001 process'" + "}"
        var callback = req.query.callback
        var jsonp = callback + '(' + data + ')'
        console.log(jsonp)
        res.send(jsonp)
        res.end()
    })
    
  • 使用 <script>标签原生实现 JSONP

  • // 服务器 3000 上的请求页面
    <script src = 'http://localhost:3001/jsonServerResponse?jsonp=jsonpCallback'></script>
    
    function jsonpCallback(data) {
        console.log("jsonpCallback: "+data.name)
    }
    
    // 服务器 3001 上对应的处理函数
    app.get('/jsonServerResponse', function(req, res) {
        var cb = req.query.jsonp
        console.log(cb)
        var data = 'var data = {' + 'name: $("#name").val() + " - server 3001 jsonp process",' + 'id: $("#id").val() + " - server 3001 jsonp process"' + '};'
        var debug = 'console.log(data);'
        var callback = '$("#submit").click(function() {' + data + cb + '(data);' + debug + '});'
        res.send(callback)
        res.end()
    })
    
  • Cross-Origin Resource Sharing(CORS)

// 服务器 3000 上的请求页面
$(function() {
    $("#submit").click(function() {
        var data = {
            name: $("#name").val(),
            id: $("#id").val()
        };
        $.ajax({
            type: 'POST',
            data: data,
            url: 'http://localhost:3001/cors',
            dataType: 'json',
            cache: false,
            timeout: 5000,
            success: function(data) {
                console.log(data)
            },
            error: function(jqXHR, textStatus, errorThrown) {
                console.log('error ' + textStatus + ' ' + errorThrown);
            }
        });
    });
});

// 服务器 3001 上对应的处理函数
app.post('/cors', function(req, res) {
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Headers", "X-Requested-With");
    res.header("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS");
    res.header("X-Powered-By", ' 3.2.1')
    res.header("Content-Type", "application/json;charset=utf-8");
    var data = {
        name: req.body.name + ' - server 3001 cors process',
        id: req.body.id + ' - server 3001 cors process'
    }
    console.log(data)
    res.send(data)
    res.end()
})

Access-Control-Allow-Origin

The origin parameter specifies a URI that may access the resource. The browser must enforce this. For requests without credentials, the server may specify “*” as a wildcard, thereby allowing any origin to access the resource.Access-Control-

Allow-Methods

Specifies the method or methods allowed when accessing the resource. This is used in response to a preflight request. The conditions under which a request is preflighted are discussed above.

Access-Control-Allow-Headers

Used in response to a preflight request to indicate which HTTP headers can be used when making the actual request.

  • window.postMessage()

  • // 服务器 3000 上的请求页面
    <script>
        window.frames[0].postMessage(data, '*');
    </script>
    <iframe src="http://localhost:3000/index.html" style="display:none" frameborder="0"></iframe>
    
    // 服务器 3001 上的页面
    <script>
        window.onmessage = function(e) {
            e = e || event;
            alert('我接受到来自外太空的数据:' + e.data);
        }
    </script>
    

results for ""

    No results matching ""