Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

怎么配置跨域资源共享 #50

Open
findxc opened this issue Jul 21, 2021 · 3 comments
Open

怎么配置跨域资源共享 #50

findxc opened this issue Jul 21, 2021 · 3 comments

Comments

@findxc
Copy link
Owner

findxc commented Jul 21, 2021

跨域资源共享,也就是 CORS,全称是 Cross-Origin Resource Sharing 。配置跨域资源共享其实就是配置一些请求头来实现的。

本地测试环境搭建

弄了一个有前端代码和后端代码的仓库来在本地进行各种测试,见 https://github.com/findxc/frontend-and-backend-playground

backend 路径下有两个文件,一个是没考虑 cookie 的跨域相关设置,一个是有考虑 cookie 的跨域相关设置。

通过 npm run start-no-cookie 或者 npm run start-need-cookie 来启动不同的前后端服务。

需要注意现在启动的前后端服务都在 localhost 这个域名下,只是端口号不一样,所以暂时 cookie 相关没有涉及到 samesite 这个问题(samesite 默认值是 lax ,而 cross-site 请求需要设为 none 后 cookie 才能使用),但是实际环境中是需要处理 samesite 问题的,因为前后端一般会在不同域名下。

这里也是涉及到一个点,originsite 的区别,两个地址如果协议或者端口号不同,会认为是不同的 origin ,但是对于 site 来说并不关心协议和端口号。

也就是跨 origin 不一样是跨 site 。

一些前置知识

什么是跨域

前端从地址 a 去请求地址 b 的资源,如果两个地址的协议、域名和端口号都一样,就认为是同域,否则就是跨域。

为什么要请求跨域资源

一些公共的服务端资源,比如 https://unpkg.com/[email protected]/dist/axios.min.js 这种,任意一个前端源都有可能会去请求这个资源。

再比如一些第三方服务,比如高德地图 api ,你去请求的时候肯定是跨域了。

什么是简单请求

参见 Simple requests

一些非简单请求的举例:

  • PUT 和 DELETE 请求;
  • content-type 为 application/json 的请求;
  • 有自定义 header 的请求;
  • 等等。

当跨域时,浏览器会自行判断一个请求是不是简单请求。

非简单请求浏览器会先发一个 OPTIONS 请求,并在请求头中携带一些实际请求的信息。然后服务端在响应头中返回允许跨域访问的一些条件。浏览器判断前端实际请求满足跨域条件时才会接着发送实际请求。

前端发请求时设置 withCredentials 是用来干啥的

当请求另外一个域的资源时,浏览器发送的请求默认是不会携带那个域的 cookie 的,服务端执行 set-cookie 操作不会报错但是实际是无效的。

只有当前端发送请求时设置了 withCredentials 为 true 并且后端响应头中设置了 Access-Control-Allow-Credentials 为 true ,跨域请求才会携带服务端域的 cookie ,服务端 set-cookie 才能成功设置上。

相关 HTTP header 解释

所有请求,包括 OPTIONS 请求都需要设置的响应头

只用 OPTIONS 请求需要设置的响应头

OPTIONS 请求头浏览器自动加上的

当服务端希望暴露某个自定义 header 给前端时

  • Access-Control-Expose-Headers:后端允许额外暴露给前端的 header ,比如某个接口后端设置了一个自定义 header ,如果没设置 Access-Control-Expose-Headers 的话前端是获取不到这个 header 的。

跨域相关的请求头就是以上这些了,本地多测测就理解了。

@GrammyLi
Copy link

这里解决的方法 是后端 自定义 http header,对吧

@findxc
Copy link
Owner Author

findxc commented Oct 20, 2021

@GrammyLi 如果只是想允许跨域,可以让运维在 nginx 那里配一下 header ,如果说某个接口想暴露额外 header 给前端,一般是后端再额外处理,如果比较通用的也可以配在 nginx 。我是这样理解的,没实战过 -.-

@findxc
Copy link
Owner Author

findxc commented Oct 20, 2021

@GrammyLi 我又想了下,我经历过的项目好像都直接后端配的。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants