如何处理浏览器跨域问题


先要明确自己的目的,然后在考虑使用哪种方法。

处理浏览器跨域问题通常涉及到 CORS(跨域资源共享)配置。CORS 是一种标准,允许服务器放宽同源策略,从而明确允许某些跨域请求,同时拒绝其他请求。如果 CORS 配置没有正确设置,浏览器控制台会显示类似 “Cross-Origin Request Blocked”(跨域请求被阻止)的错误消息。

如何处理浏览器跨域问题


1. Nginx 处理跨域问题

Nginx - 可以参考之前的 博客笔记

使用 Nginx 解决浏览器的跨域资源共享(CORS)问题,你需要在 Nginx 服务器上设置相应的响应头。这些响应头将告诉浏览器哪些来源是被允许的,从而解决跨域请求的问题。

# 使用Nginx的add_header指令来添加Access-Control-Allow-Origin响应头
location / {
    add_header 'Access-Control-Allow-Origin' '*';
}

# 对于预检请求(OPTIONS请求),需要添加额外的响应头
# 如Access-Control-Allow-Methods和Access-Control-Allow-Headers响应头
location / {
    if ($request_method = 'OPTIONS') {
        add_header 'Access-Control-Allow-Origin' '*';
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'Authorization, Origin, X-Requested-With, Content-Type, Accept';
        return 200;
    }
}

# 如果使用了Access-Control-Allow-Credentials
# 需要确保响应头中的Access-Control-Allow-Origin与请求中的Origin一致
if ($http_origin = ''){
    set $http_origin "*";
}
proxy_hide_header Access-Control-Allow-Origin;
add_header Access-Control-Allow-Origin $http_origin;

2.  Preflight 处理跨域问题

POST + Preflight

POST+Preflight 是一种前端的跨域请求方式,这种跨域请求方式可以有效地保护服务器的安全性,防止恶意攻击。当使用 POST 请求并且请求头中包含一些特殊的信息(如自定义的 header 字段)时,浏览器会先发送一个 Preflight 请求,该请求的方法为 OPTIONS 类型,用来询问服务器是否允许跨域请求以及哪些请求头可以使用。服务器返回允许的请求头后,浏览器才会发送真正的 POST 请求。

  • 有一个前端页面在 a.com 域名下,需要向 b.com 域名下的服务器发送一个 POST 请求,请求头中包含了一个自定义的 header 字段 “X-Token“。当发送这个请求时,浏览器会先发送一个 Preflight 请求,询问服务器是否允许跨域请求以及哪些请求头可以使用。

  • 这个请求中包含了一些特殊的请求头字段(发送 Preflight 请求)

    • Access-Control-Request-Method:表示实际请求中使用的 HTTP 方法
    • Access-Control-Request-Headers:表示实际请求中使用的自定义请求头
    • Origin:发起请求的域名
OPTIONS /api/user HTTP/1.1
Host: b.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: X-Token
Origin: http://a.com
  • 这个响应中包含了以下响应头字段(响应的 Preflight 请求)
    • Access-Control-Allow-Origin:表示允许哪些域名的请求
    • Access-Control-Allow-Methods:表示允许跨域请求的 HTTP 方法
    • Access-Control-Allow-Headers:表示允许跨域请求的自定义请求头
HTTP/1.1 200 OK
Access-Control-Allow-Origin: http://a.com
Access-Control-Allow-Methods: POST
Access-Control-Allow-Headers: X-Token
  • 这个请求中包含了以下请求头字段(发送真正的 POST 请求)
    • Content-Type:表示请求体的类型
    • X-Token:表示自定义的请求头
    • Origin:发起请求的域名
POST /api/user HTTP/1.1
Host: b.com
Content-Type: application/json
X-Token: abcdefg
Origin: http://a.com
{"name": "Alice", "age": 18}

在浏览器中通过 JS 代码发送跨域请求时(比如从 a.com 的页面向 b.com 的服务器发送请求),浏览器会先检查当前请求是否符合同源策略,如果不符合就会阻止这个请求。这时我们需要使用 CORS(跨域资源共享)机制来允许跨域请求。

CORS 机制中,浏览器会使用预检请求(Preflight request)来检查服务端是否允许跨域请求。如果服务端支持跨域请求,它会返回一些特殊的响应头,告诉浏览器可以发送真正的跨域请求。如果服务端不支持跨域请求,它会返回一些错误信息,浏览器会阻止这个请求。


3. Jsonp 处理跨域问题

Jsonp

JSONP(JSON with Padding)是一种跨域解决方案,它利用了 <script> 标签可以跨域加载资源的特性,实现浏览器与服务器之间的跨域数据传输。具体来说,它通过在请求 URL 中添加回调函数名的方式,让服务器返回一段 JavaScript 代码,浏览器接收到响应后会自动执行这段代码,从而实现跨域数据传输。

JSONP 的工作原理如下所示:

  1. 客户端在页面中创建一个 <script> 标签,并指定请求的 URL,同时在 URL 中添加一个回调函数名作为参数,例如:
<script src="http://example.com/data?callback=handleData"></script>
  1. 服务器接收到请求后,会将数据封装在一个函数调用中,函数名就是客户端指定的回调函数名,例如:
handleData({ name: "Alice", age: 18 });
  1. 服务器返回上述代码,浏览器接收到响应后会自动执行 handleData 函数。这样,客户端就可以在 handleData 函数中获取服务器返回的数据了。

JSONP 的优点是实现简单,兼容性好,在一些老旧的浏览器中也可以使用。但是它也有一些缺点,比如只支持 GET 请求,不支持 POST 等其他类型的请求,同时也存在安全性问题,容易受到 XSS 攻击。因此,现在更多的开发者选择使用 CORS(跨域资源共享)来解决跨域问题。


文章作者: Escape
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Escape !
  目录