跨域:JSONP与CORS

本文深入探讨跨域问题的成因及解决策略,重点讲解JSONP与CORS两种主流跨域方式的工作原理、使用方法及优缺点,通过实战演练加深理解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、跨域

跨域问题一般只出现在前端开发中使用 javascript 进行网络请求的时候,浏览器为了安全访问网络请求的数据而进行的限制。

为什么会产生跨域?

同源策略:协议、域名、端口三者相同,有一个不相同就是不同源

同源限制了哪些行为?

  1. Cookie、Localstorage和IndexDB无法读取
  2. DOM和JS对象无法获取
  3. Ajax请求发送不出去

解决JS跨域问题的方法有8种:

  1. JSONP(只支持get)
  2. 反向代理
  3. CORS
  4. document.domain + iframe跨域
  5. window.name + iframe跨域
  6. window.postMessage
  7. location.hash + iframe
  8. web socket

各个方法都有各自的优缺点,但是目前前端开发方面比较常用的是 JSONP,反向代理,CORS。

二、这里介绍两种跨域方式:JSONP与CORS

(一)JSONP 

JSONP 全称 JSON with Padding,是数据格式 JSON 的一种 “使用模式”,可用于解决主流浏览器的跨域数据访问的问题。

JSONP 是一种非正式传输协议,该协议的一个要点就是允许用户传递一个 callback 参数给服务端,然后服务端返回数据时会将这个 callback 参数作为函数名来包裹住 JSON 数据,这样客户端就可以随意定制自己的函数来自动处理返回数据了。

JSONP原理:

  • 利用script标签不受同源策略影响,可以跨域引入外部资源的特性,让服务器端返回可执行的JS函数,将要返回的数据作为参数传进函数,以此实现跨域加载数据的目的。
  • 此时绕过Ajax,并未使用它,但同样达到请求数据的目的。

script标签引用资源的本质是:

  • 向src发送请求
  • 将资源下载到当前页面
  • 当资源加载完毕后,把该资源当做JS代码来立即执行

JSONP的使用:

  1. 动态创建script标签,src地址指向数据接口,并传递callback参数
  2. 定义数据处理函数
  3. 服务端接受请求,解析参数,计算数,返回回调函数字符串
  4. 将回调函数字符串引入页面并作为计算去执行:此时会调用数据处理函数,数据会作为数据处理函数的参数被处理计算出一个结果

JSONP的优缺点:

  • 优点:script标签属于HTML标签,不存在兼容性问题
  • 缺点:

  1. 因使用url引入资源,所以JSONP仅支持get请求
  2. 因script标签会作为资源作为JS代码执行,所以可能被注入恶意代码

JSONP 演练:

  • 演练说明
    1)实现的功能:非同源情况下,点击按钮,请求数据,并将数据展示在页面上
    2)当前页面域:a.yang.com ;script 的 src 属性:b.yang.com;
    3)请求的数据:长度为10的随机字符串,选值范围为26个小写英文字母
  • 搭建 web 服务器工具:server-mock

前端index代码

var btn = document.querySelector('.btn'),
	panal = document.querySelector('.panal');
btn.addEventListener('click', function () {
	var script = document.createElement('script');
	script.src = 'http://b.yang.com:8080/loadData?callback=onSuccess';
	document.head.appendChild(script);
	document.head.removeChild(script);
});
function onSuccess(data) {
	panal.innerText = data;
}

服务端 router 代码

app.get('/loadData', function(req, res) {
	var dataStr = '';
	var len = 10;
	var disc = 'abcdefjhigklmnopqrstuvwxyz';
	for(var i = 0; i < len; i++){
		dataStr += disc[Math.floor(Math.random() * disc.length)];
	}
	var callback = req.query.callback;
	data = callback + '(' + JSON.stringify(dataStr) + ');';
	res.send(data);
});

尝试改变当前页面的域,与 AJAX 请求域相同或不同,体会一下浏览器的跨域请求、报错提示、同源策略、实现跨域请求。

(二)CORS

CORS 就是一种跨域问题的解决方案:它定义了一种跨域访问的机制,允许网页从不同的域访问其资源。与 JSONP 相比,更为方便可靠。

CORS 全称 Cross-Origin Resource Sharing,即:跨来源资源共享。它是一份浏览器技术的规范,提供了Web服务从不同网域传来沙盒脚本的方法,以避开浏览器的同源策略,是JSONP模式的现代版。

CORS 的原理:

  1. 当使用 XMLHttpRequest 发送请求时,如果浏览器发现该请求不符合同源策略,会给该请求加一个请求头:Origin;
  2. 后台进行一系列处理,如果确定接受请求则在返回结果中加入一个响应头:Access-Control-Allow-Origin;
  3. 浏览器判断该响应头中是否包含 Origin 的值:
  4. 如果包含浏览器则会处理响应,前端就可以拿到响应数据;
  5. 如果不包含浏览器直接驳回,此时前端无法拿到响应数据。

简单来说,就是浏览器匹配请求头和响应头,如果符合要求便可拿到数据,否则无法拿到数据。整个过程都是由浏览器自动完成。这就像一个白名单,代表着谁可以拿到数据。

CORS 的使用

  • 前端:正常使用 AJAX 发送请求

  • 服务端:若确定接受请求,则在返回结果中加入响应头:Access-Control-Allow-Origin

CORS 的优缺点

  • 优点
  1. 使用简单方便、更为安全
  2. 支持 POST 请求方式
  • 缺点:CORS 是一种新型跨域问题的解决方案:存在兼容问题——仅支持 IE10 以上

CORS 的演练

  • 演练说明
    1)实现的功能:非同源情况下,点击按钮,请求数据,并将数据展示在页面上
    2)当前页面域:a.yang.com ;Ajax 请求域:b.yang.com;
    3)请求的数据:长度为10的随机字符串,选值范围为26个小写英文字母
    4)请求方式:post
  • 搭建 web 服务器工具:server-mock

前端index代码

var btn = document.querySelector('.btn'),
        panal = document.querySelector('.panal');

    btn.addEventListener('click', function () {
        var xhr = new XMLHttpRequest();
        xhr.onreadystatechange = function () {
            if(xhr.readyState === 4){
                if(xhr.status === 200){
                    onSuccess(xhr.responseText);
                }
            }
        }
        xhr.open('post', 'http://b.yang.com:8080/loadData', true);
        xhr.send();
    });

    function onSuccess(data) {
        panal.innerText = data;
    }

服务端 router 代码

app.post('/loadData', function(req, res) {
        var disc = 'abcdefjhigklmnopqrstuvwxyz';
        var data = '';
        for(var i = 0; i < 10; i++){
            data += disc[Math.floor(Math.random() * disc.length)];
        }
        res.header("Access-Control-Allow-Origin", "http://a.yang.com:8080");
        res.send(data);
});

尝试改变当前页面的域,与 AJAX 请求域相同或不同,体会一下浏览器的跨域请求、报错提示、同源策略、实现跨域请求。

最后:jsonp 和 cors 都是主流的跨域方式,最主要的还是看需求,其中最大的问题就是兼容程度,请按需选择。

 

参考资料:

  1. jsonp-反向代理-CORS解决JS跨域问题的个人总结
  2. 跨域之二:JSONP 和 CORS
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值