2020-05-01 JSONP和CORS

135 阅读1分钟

场景:

某天拿到一个接口,可以用来查询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.怎么算是不同源?

3.只限制从脚本内发起的跨源HTTP请求,意思就是html标签发起的不算(为JSONP埋下伏笔),比如<img>标签的src,<script>标签的src等等。

注:有人问为什么在浏览器地址栏访问没有产生跨域呢?如果本地起了一个服务发起一个ajax请求,你本地的服务一个域,服务端一个域,不一样所以跨域了;而在浏览器地址栏上直接输入url来发起一个请求,就只存在服务端这一个域。**


JSONP(JSON with Padding)

JSONP是通过 script 标签加载数据的方式去获取数据当做 JS 代码来执行,只支持GET请求\color{red}{只支持GET请求},代码如下:

    <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 方式处理跨域前后端代码如何配合

ajax发送http请求会有跨域问题,为啥在浏览器地址栏上输入同样的url没有跨域问题?