欢迎访问宙启技术站
智能推送

WEB跨域请求

发布时间:2023-05-18 09:08:12

跨域是指在进行网络请求时,发起请求的源和响应的目标不在同一个域名下。在前端开发中,跨域问题是非常常见的。例如,当网站a.com的网页需要请求b.com的数据时,就会出现跨域问题,导致请求失败。本文将从以下方面展开对跨域请求的介绍:跨域请求的原因、跨域解决方案、JSONP原理及应用、CORS原理及应用。

一、跨域请求的原因

产生跨域请求的原因是浏览器的同源策略。同源策略是一套约定,属于浏览器的安全策略,它主要限制了一个源加载的文档或脚本如何与来自另一个源加载的资源进行交互。具体来说,同源策略要求请求方和响应方的域名、协议、端口号都必须相同。如果不同,则会产生跨域请求问题。

二、跨域解决方案

1. 跨域请求解决方案一:JSONP

JSONP 的原理是利用 <script> 标签没有跨域限制的漏洞。通过 <script> 标签来引入一个 js 文件,这个 js 文件载入成功后会执行我们在 URL 参数中指定的函数,并且会把我们需要的 JSON 数据作为参数传入。因为同源策略的限制,XMLHttpRequest 对象只在同源的情况下才能发起请求,而通过 <script> 标签可以绕过这个限制。

2. 跨域请求解决方案二:CORS

CORS(Cross-Origin Resource Sharing)是 W3C 的标准,全称是跨域资源共享。CORS 是一种跨域请求方式,被用于解决 AJAX 请求时的跨域限制。CORS 要求服务器在响应中加上一个 Access-Control-Allow-Origin 的头部,表示允许的源列表,浏览器只会针对该列表中的源进行跨域请求,其他源则不允许跨域请求。这个跨域请求的过程分为预检(Preflighted requests)和正式请求(Actual requests)两个阶段。

三、JSONP原理及应用

JSONP (JSON with Padding)是一种跨域请求方案,利用 <script> 标签的特性绕过浏览器的同源限制来获取数据。JSONP 的处理流程如下:

1. 客户端定义回调函数。

2. 发起 <script> 请求,请求的 URL 最后一个参数为定义的回调函数名。

3. 服务端接收到请求后,根据参数包装需要返回的数据,并将返回值作为参数传入到客户端定义的回调函数中。

4. 客户端接收到响应后,执行定义的回调函数,完成数据处理。

JSONP 的应用:当我们需要跨域获取数据时,常见的方法是使用 JSONP,例如百度地图 API 和淘宝 API 等。下面我们以百度天气 API 为例展示 JSONP 的使用。

1. 定义回调函数:

function handleResponse(data) {
  console.log(data);
}

2. 发起 <script> 请求:

<script src="http://api.map.baidu.com/telematics/v3/weather?location=深圳&output=json&ak=你的ak值&callback=handleResponse"></script>

注:这里使用了百度天气 API,使用时需要替换你自己的 ak 值。

3. 服务端返回数据:

服务端在接收到请求后,会将数据包装成如下形式的 JSON 数据,并将其作为参数传入到 handleResponse 函数中:

handleResponse({
    "error": 0,
    "status": "success",
    "results": [{
        "currentCity": "深圳市",
        "pm25": "72",
        "weather_data": [
            {
                "date": "周二 07月10日",
                "dayPictureUrl": "http://api.map.baidu.com/images/weather/day/yin.png",
                "nightPictureUrl": "http://api.map.baidu.com/images/weather/night/xiaoyu.png",
                "weather": "阴转小雨",
                "wind": "无持续风向",
                "temperature": "30 ~ 25℃"
            }
        ]
    }]
})

四、CORS原理及应用

CORS 是一种跨域请求方式,它允许异域的服务器在 HTTP 响应头中指定允许的来源(Origins)、方法(Methods)、请求头字段(Headers)、响应头字段(Headers)等,浏览器在发起请求时会先发一次预检请求,询问服务器是否允许该请求,只有得到确认的才会发起实际请求。

CORS 的应用:下面我们以使用 Axios 发起 CORS 请求为例,展示 CORS 的使用方法。

1. 定义请求:

axios.get('https://some-domain.com/api/data', {
  withCredentials: true
})
  .then(response => {
    console.log(response);
  })
  .catch(error => {
    console.log(error);
  });

2. 服务端设置:

服务端需要在响应头中加上 Access-Control-Allow-Origin 和 Access-Control-Allow-Credentials 这两个字段,如下:

Access-Control-Allow-Origin: https://foo.com
Access-Control-Allow-Credentials: true

这样,只有来自 https://foo.com 的请求,才会允许跨域请求和携带凭证信息。如果要允许所有来源的跨域请求,就可以将 Access-Control-Allow-Origin 的值设置为 *。

注:CORS 请求时,如果设置了 withCredentials 为 true,则代表这是一个带凭证的请求,浏览器会向服务端发起包含 Cookie 等凭证信息的请求。

总结:跨域请求是前端开发中常见的问题,常用的解决方案是 JSONP 和 CORS,分别利用了 <script> 标签的漏洞和浏览器的跨域策略。使用时,需要针对具体场景进行选择,同时注意安全性和性能问题。