HTTP跨域请求
平常工作中我们都会遇到浏览器跨域问题,特别是前端同学,由于经常要获取后端api,如果api域名和前端域名不一致将会导致跨域亲求问题.如何解决跨域请求问题?
本文将列出解决跨域请求的两个方法.
一. 从后端入手允许跨域
需要在后端返回的请求头部添加如下字段:
- Access-Control-Allow-Origin
如
Access-Control-Allow-Origin: *
*值表示该资源可以被任意的外源网址访问
如果只想指定某个源地址访问,直接指定网址地址即可, 如只允许example.com访问:
Access-Control-Allow-Origin: https:example.com
如果想指定多个外源地址访问呢?
Access-Control-Allow-Origin不支持同时指定多个域名,如:
Access-Control-Allow-Origin: https:example.com, https:example-1.com
也不支持在同一个响应头中返回多个Access-Control-Allow-Origin 如:
Access-Control-Allow-Origin: https:example.com
Access-Control-Allow-Origin: https:example-1.com
这些都是无效的
正确的做法是后端维护一个允许访问的外源地址列表,当请求地址在该列表中,将该地址作为Access-Control-Allow-Origin值返回即可
- Access-Control-Allow-Methods
该字段指定了访问资源时允许使用的请求方法,用于预检请求的响应。其指明了实际请求所允许使用的 HTTP 方法.
Access-Control-Allow-Methods: GET,POST,PUT,DELETE
未列出的方法将不允许源站使用该方法请求资源,正对上面的示例,原站如果使用PATCH方法将不能请求资源.
Access-Control-Allow-Methods: *
*将允许所有HTTP请求方法
- Access-Control-Allow-Headers
Access-Control-Allow-Headers 标头字段用于预检请求的响应。其指明了实际请求中允许携带的标头字段。这个标头是服务器端对浏览器端 Access-Control-Request-Headers 标头的响应。
Access-Control-Allow-Headers: Date, Content-Type, Server
示例只允许源站读取服务端的Date, Content-Type, Server等响应头信息, 如果Access-Control-Allow-Headers值设置为*,则允许源站读取所有响应头信息.
为了服务端资源的安全,不推荐将 Access-Control-Allow-Origin,Access-Control-Allow-Methods, Access-Control-Allow-Headers 等头部信息值设置为*,我知道大部分人为了简单方便,为了能快速解决问题,一套操作猛如虎,全部设置成*,导致的后果就是网络中的任何人都能访问你的资源.
二. Nginx绕过跨域问题
如果后端域名在你的控制之内,如后端就是你自己开发的或者同一个项目组的同学开发的,那么你可以将后端域名和和前端保持一致,如前端frontend.example.com,后端用backend.example.com,这样以来就根本上解决的跨域问题,因为前端和后端都在同一个域名中.
如果你不想后端也使用域名,或者后端域名不可改动,那么使用Nginx转发以下即可解决.
server {
listen 80;
server_name example.com;
location /api/ {
proxy_pass https://example-1.com;
}
}
以上示例当浏览器访问https://example.com/api/时,nginx转发请求到https://example-1.com上,对浏览器而言,请求api资源访问的还是example.com这个域名,所以不存在跨域.