B/S架构的项目中前端经常会遇到跨域问题,什么是跨域问题,常用的解决方法又有哪些呢?可能大多数人对跨域问题都只是一知半解吧。
先来说说那么到底什么是跨域?跨域是指一个域下的文档或脚本去请求另一个域下的资源。跨域问题则是指浏览器出于安全考虑而需要遵循同源策略,限制不同源的网站的文件的执行,同源指的是“协议+域名+端口号”都相同。
如果非同源,如下三种行为会受到限制:
必须明确以下几点:
那么为什么浏览器才有跨域问题而App不会存在跨域问题呢?很简单,app是自家的,所有的请求都是到自家的服务器,而浏览器是可以访问很多网站的,每个网站都可以带有cookie等信息,如果被其他恶意网站利用,后果不堪设想。
跨域的解决方案很多,有如下几种:
常用的方案有:
CROS全称是跨域资源共享(Cross-origin resource sharing),它的提出就是为了解决跨域请求的。跨域资源共享(CORS)标准新增了一组 HTTP 首部字段,允许服务器声明哪些源站有权限访问哪些资源。
对于简单请求服务器配置后直接接受请求,对于对那些可能对服务器数据产生副作用非简单的HTTP请求方法(特别是GET以外的HTTP请求,或者搭配某些MIME类型的POST请求),浏览器必须首先使用OPTIONS方法发起一个预检请求(preflight request),从而获知服务端是否允许该跨域请求。
我们上面说过,浏览器跨域时其实请求已经发送到服务器了并返回了结果,那如果服务器配置了是允许跨域的,浏览器是否就会放行呢?答案是肯定的,当浏览器拿到响应头Access-Control-Allow-Origin: *
时,会匹配其中的允许跨域的网址是否有自己,有的话则接收响应执行。如下,我在服务端Spring Boot配置了注解,成功跨域。
服务端配置:当然你可以配置成全局的,不用每个类都写注解
响应如下:
CORS除了上面简单使用Spring Boot注解配置外,还可以使用Nginx配置。如下,对于非简单请求,浏览器总共会发两次请求,第一次是预检请求OPTIONS。
location / { add_header Access-Control-Allow-Origin *; add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS'; add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization'; if ($request_method = 'OPTIONS') { return 204; } } 复制代码
JSONP的原理是利用了