返回博主主页

跨域配置

在 web 应用程序中,当发起一个跨域请求,

MDN-access-controll

A.example.com 发送请求

POST 请求会发送一个预检请求(OPTIONS),GET 不会
首先是请求。预检请求是 OPTIONS 包含三个预检请求标头的某种组合的请求: Access-Control-Request-MethodAccess-Control-Request-HeadersOrigin
image

如控制台提示如下内容:

Access to XMLHttpRequest at 'http://B.example.com' from origin 'http://A.example.com' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.
POST http://B.example.com/XXX net::ERR_FAILED

可以在 http://B.example.com 请求拦截器判断,如过是预检请求,就返回 200 状态码

# python flask
@app.before_request
def before_rest_request():
    if request.method == 'OPTIONS':
        response = make_response('ok')
        response.status_code = 200
        return response
    else:
        # 放行
        return None

B.example.com 响应配置响应标头

可在请求拦截器响应处添加标头、或者在负载均衡器响应添加标头
Access-Control-Allow-Headers
Access-Control-Allow-Credentials
Access-Control-Allow-Methods
Access-Control-Allow-Origin

Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: Content-Type, Authorization
Access-Control-Allow-Methods: POST, GET,PUT,OPTIONS,DELETE
Access-Control-Allow-Origin: $http_Origin

CORS 访问不通过,chrome 控制台的一些提示

  • 缺失 Access-Control-Allow-Credentials
Access to XMLHttpRequest at 'http://B.example.com' from origin 'http://A.example.com' has been blocked by CORS policy: 
The value of the 'Access-Control-Allow-Credentials' header in the response is '' which must be 'true' when the request's credentials mode is 'include'. 
The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.

解决办法:配置B.example.com的响应头

Access-Control-Allow-Credentials: true

当请求的凭据模式包括 ( Request.credentials )时,浏览器只会在 Access-Control-Allow-Credentials 值为 true 时,将响应暴露给前端 JavaScript 代码。

fetch(url, {
  credentials: "include",
});

import axios from 'axios'
import store from '@/store';
// create an axios instance
const service = axios.create({
    // baseURL: "custom base url", // url = base url + request url
    withCredentials: true, // send cookies when cross-domain requests
    timeout: 300000, // request timeout
    headers: {
        'Content-Type': 'application/json;charset=UTF-8'
    }
})

注意: Access-Control-Allow-Credentials 设置为 true,Access-Control-Allow-Origin不能设置为星号(*),而应该指定具体的域名或IP地址($http_Origin)。

结果

B.example.com 配置好OPTIONS和响应标头之后,A.example.com 就能正常访问B.example.com的资源
image

posted @ 2024-01-02 20:59  懒惰的星期六  阅读(22)  评论(0编辑  收藏  举报

Welcome to here

主页