场景:
某天拿到一个接口,可以用来查询jd产品的价格(p.3.cn/prices/mget… iphone11的价格),把 URL复制到浏览器浏览器地址栏按下回车键,页面展示了查询商品的价格信息:[{"cbf":"0","id":"J_100008348542","m":"6000.00","op":"5999.00","p":"5999.00"}]
于是写了个页面,使用 ajax 调用当前接口,代码如下:
$.get( "https://p.3.cn/prices/mgets?skuIds=J_100008348542&type=1")
.then((res) => console.log(res));
结果控制台报错如下:
这就是跨域的问题了。
CORS(Cross-Origin Resource Sharing,跨域资源共享)
CORS是一种机制,它使用额外的 HTTP 头来告诉浏览器 让运行在一个 origin (domain) 上的Web应用被准许访问来自不同源服务器上的指定的资源。当一个资源从与该资源本身所在的服务器不同的域、协议或端口请求一个资源时,资源会发起一个跨域 HTTP 请求。 出于安全原因,浏览器限制从脚本内发起的跨源HTTP请求。
我们需要关注的点有:
1.跨域产生原因是浏览器的同源策略。(为了安全)
2.怎么算是不同源?
- 协议不同:http 和 https
- 主域不同: www.domain001.com 和 www.domain002.com
- 端口号不同 localhost:8088 和 localhost:9000。
3.只限制从脚本内发起的跨源HTTP请求,意思就是html标签发起的不算(为JSONP埋下伏笔),比如<img>标签的src,<script>标签的src等等。
注:有人问为什么在浏览器地址栏访问没有产生跨域呢?如果本地起了一个服务发起一个ajax请求,你本地的服务一个域,服务端一个域,不一样所以跨域了;而在浏览器地址栏上直接输入url来发起一个请求,就只存在服务端这一个域。**
JSONP(JSON with Padding)
JSONP是通过 script 标签加载数据的方式去获取数据当做 JS 代码来执行,,代码如下:
<script>
function showData(data) {
console.log(data);
}
</script>
<script src="https://p.3.cn/prices/mgets?skuIds=J_100008348542&type=1&callback=showData"></script>
jQuery写法:
!(function () {
$.ajax({
url: "https://p.3.cn/prices/mgets?skuIds=J_100008348542&type=1",
type: "GET",
dataType: "jsonp",
jsonp: "callback",
success: function (res) {
console.log(res);
},
});
})();
加了一个callback参数,注意,这个是与后台约定的参数,如果不设置默认为callback
参考 :
若愚老师 「每日一题」JSONP 是什么?
MDN HTTP访问控制(CORS)
winyh jsonp 方式处理跨域前后端代码如何配合