利用 JSONP 处理跨域请求问题


现代浏览器都遵守同源策略,即要求一些请求的资源必须与 url 属于同一域名,以防止跨域攻击等恶性行为发生。但有时候前端需要去访问非同源资源时,如果不支持在 Header 里加入 ” Access-Control-Allow-Origin” 就不太好办了。

另一种方法是改为在服务端获取并渲染站外资源,但这样做效率很低,还容易被封。拿服务器做个代理也可以,但是太复杂没有必要。

此时,我们可以尝试利用 JSONP 解决跨域请求问题。

请求代码如下:

jQuery.ajax({
    url: 'https://labs.bible.org/api/',
    dataType: 'jsonp',
    data: {
        'passage': 'random',
        'formatting': 'plain',
        'type': 'json',
        'callback': 'bibleup'
    }
});

我所选择的 API 提供者服务端在收到请求中的 callback 参数时,便会在返回数据中要求回调 bibleup 这个函数,具体请参考 API 提供商。

例如,发送以下请求:

curl "https://labs.bible.org/api/?type=json&callback=bibleup&formatting=plain&passage=random"

得到返回的 JSONP 数据为:

bibleup([{
    "bookname": "Romans",
    "chapter": "11",
    "verse": "5",
    "text": "So in the same way at the present time there is a remnant chosen by grace."
}])

它以 JSON 为参数调用了回调函数。回调函数代码:

var bibleup = function (json) {
    let bookname = json[0].bookname;
    let chapter = json[0].chapter;
    let verse = json[0].verse;
    let text = json[0].text;
    text = text.substring(0, text.indexOf("<a"));
    let output = `<b>${bookname} ${chapter}</b> <br> <small> ${verse} </small> ${text}`;
    jQuery('#random-bible').html(output);
}

如此一来,就可以轻松实现跨域请求了。