重庆市建设公共资源交易中心网站首页,初创公司 建网站,wordpress修改文章页面模板,宁波seo快速优化平台跨域是浏览器的一种同源策略#xff0c;所以该概念只存在于通过浏览器访问服务里。
如果缺少了同源策略#xff0c;则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的#xff0c;浏览器只是针对同源策略的一种实现 请求的url地址,必须与浏览器上的…跨域是浏览器的一种同源策略所以该概念只存在于通过浏览器访问服务里。
如果缺少了同源策略则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的浏览器只是针对同源策略的一种实现 请求的url地址,必须与浏览器上的url地址处于同域上,也就是域名,端口,协议相同. 比如:我在本地上的域名是127.0.0.1:8000,请求另外一个域名127.0.0.1:8001一段数据 浏览器上就会报错这个就是同源策略的保护,如果浏览器对javascript没有同源策略的保护,那么一些重要的机密网站将会很危险 已拦截跨源请求同源策略禁止读取位于 http://127.0.0.1:8001/SendAjax/ 的远程资源。原因CORS 头缺少 Access-Control-Allow-Origin。 但是注意项目2中的访问已经发生了说明是浏览器对非同源请求返回的结果做了拦截
1|2CORS跨域资源共享简介 CORS需要浏览器和服务器同时支持。目前所有浏览器都支持该功能IE浏览器不能低于IE10。 整个CORS通信过程都是浏览器自动完成不需要用户参与。对于开发者来说CORS通信与同源的AJAX通信没有差别代码完全一样。浏览器一旦发现AJAX请求跨源就会自动添加一些附加的头信息有时还会多出一次附加的请求但用户不会有感觉。 因此实现CORS通信的关键是服务器。只要服务器实现了CORS接口就可以跨源通信。
1|3CORS基本流程 浏览器将CORS请求分成两类简单请求simple request和非简单请求not-so-simple request。 浏览器发出CORS简单请求只需要在头信息之中增加一个Origin字段。 浏览器发出CORS非简单请求会在正式通信之前增加一次HTTP查询请求称为”预检”请求preflight。浏览器先询问服务器当前网页所在的域名是否在服务器的许可名单之中以及可以使用哪些HTTP动词和头信息字段。只有得到肯定答复浏览器才会发出正式的XMLHttpRequest请求否则就报错。
1|4CORS两种请求详解
只要同时满足以下两大条件就属于简单请求。 1) 请求方法是以下三种方法之一 HEAD GET POST 2HTTP的头信息不超出以下几种字段 Accept Accept-Language Content-Language Last-Event-ID Content-Type只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain
凡是不同时满足上面两个条件就属于非简单请求。浏览器对这两种请求的处理是不一样的 * 简单请求和非简单请求的区别 简单请求一次请求 非简单请求两次请求在发送数据之前会先发一次请求用于做“预检”只有“预检”通过后才再发送一次请求用于数据传输。 * 关于“预检” - 请求方式OPTIONS - “预检”其实做检查检查如果通过则允许传输数据检查不通过则不再发送真正想要发送的消息 - 如何“预检” 如果复杂请求是PUT等请求则服务端需要设置允许某请求否则“预检”不通过 Access-Control-Request-Method 如果复杂请求设置了请求头则服务端需要设置允许某请求头否则“预检”不通过 Access-Control-Request-Headers
支持跨域简单请求 服务器设置响应头Access-Control-Allow-Origin ‘域名’ 或 ‘*’ 支持跨域复杂请求 由于复杂请求时首先会发送“预检”请求如果“预检”成功则发送真实数据。 “预检”请求时允许请求方式则需服务器设置响应头Access-Control-Request-Method “预检”请求时允许请求头则需服务器设置响应头Access-Control-Request-Headers
关于服务端接收到预检请求后分析CORS请求头中的内容决定是否允许该请求这个详细流程和步骤是怎么样的具体做了哪些检查
预检请求的目的是为了让服务端知道客户端的跨域请求信息并决定是否允许这个跨域请求。下面是服务端处理CORS预检请求的详细流程和步骤
1. 收到CORS预检请求后服务端首先校验该请求的method是否为OPTIONS如果不是OPTIONS则服务端直接返回HTTP错误码 405 Method Not Allowed。
2. 服务端进一步检查CORS请求头中的Origin字段确认该请求是否来自允许的域名。如果Origin字段不在允许的域名列表中服务端会直接返回HTTP错误码403 Forbidden。
3. 如果Origin字段在允许的域名列表中服务端会检查CORS请求头中的Access-Control-Request-Method字段判断实际请求是否支持该方法。如果服务器端不支持该方法会直接返回HTTP错误码 405 Method Not Allowed。
4. 如果服务器端支持该方法继续检查CORS请求头中的Access-Control-Request-Headers字段确认所有请求头字段是否都被允许。如果有请求头字段没有在服务器端允许的请求头列表中服务端会拒绝该请求并返回HTTP错误码 403 Forbidden。
5. 如果所有检查都通过了服务端可以根据配置的跨域策略通过在响应头中设置Access-Control-Allow-*字段来告诉浏览器可以执行跨域请求。例如设置Access-Control-Allow-Origin字段为请求头中的Origin值表示允许该域名跨域访问。
6. 服务端发送响应头信息告诉浏览器CORS预检请求允许通过。浏览器收到允许的响应头信息后会发送第二个实际请求并在请求头中携带CORS相关的信息服务端接收到这个实际请求后可以进行正常的数据处理并返回响应数据。
综上所述服务端在处理CORS预检请求时需要根据CORS请求头中的Origin、Access-Control-Request-Method和Access-Control-Request-Headers字段对该跨域请求的域名、方法和请求头信息进行有效性检查并根据服务端的跨域配置策略返回恰当的响应头信息来告诉浏览器是否允许该跨域请求。
如果浏览器发送了一个OPTIONS请求服务端怎么知道是需要校验跨域请求
当浏览器发送OPTIONS请求时服务端会检查此请求是否携带了CORS相关的请求头信息。如果携带了跨域请求的请求头信息则服务端会理解该请求是一次CORS请求进行进一步的处理。
具体来说CORS请求头中至少包含了Origin字段该字段表示请求的源服务端通过跟自己存储的允许跨域请求的域名列表对比判断该请求是否允许跨域。
另外在OPTIONS请求中还会包含Access-Control-Request-Method和Access-Control-Request-Headers两个字段用于告诉服务端实际请求将使用哪种方法和请求头字段。服务端可以根据这些信息判断实际请求是否被允许。
如果服务端检查后发现该请求是一次跨域请求就会根据CORS策略决定是否向浏览器发送响应头信息告知浏览器是否允许实际请求跨域。如果服务端认为该跨域请求不合法则会拒绝该请求不做任何处理或者返回适当的错误信息。
不同的配置CORS的方式
1.可以通过Corsorigin注解配置
https://blog.csdn.net/securitit/article/details/113251401
2.可以通过springboot 配置文件里配置示例如下 通过配置文件的方式是全局生效如果想在方法级别控制CORS就用Corsorigin注解吧
这两种方法实现的原理都是通过spring 拦截器实现大概步骤如下
/** 在配置文件中很难实现方法级别的跨域请求控制因为配置文件是全局生效的无法对单独的方法进行定制。如果你需要实现方法级别的跨域请求控制可以考虑使用框架提供的注解或拦截器来进行处理。以Spring Boot框架为例你可以在方法上使用CrossOrigin注解指定方法允许的跨域请求来源也可以使用拦截器对特定的方法进行跨域请求控制。以下是使用拦截器实现方法级别跨域请求控制的一个例子
**/Configuration
public class CorsConfig implements WebMvcConfigurer {Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new CorsInterceptor()).addPathPatterns(/hello);}
}public class CorsInterceptor implements HandlerInterceptor {Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {if (handler instanceof HandlerMethod) {HandlerMethod handlerMethod (HandlerMethod) handler;CrossOrigin annotation handlerMethod.getMethodAnnotation(CrossOrigin.class);if (annotation ! null) {String[] allowedOrigins annotation.origins();String origin request.getHeader(Origin);if (Arrays.asList(allowedOrigins).contains(origin)) {response.setHeader(Access-Control-Allow-Origin, origin);response.setHeader(Access-Control-Allow-Methods, POST, GET, OPTIONS);response.setHeader(Access-Control-Allow-Headers, content-type);return true;}response.setStatus(HttpServletResponse.SC_FORBIDDEN);return false;}}return true;}
}这个例子中我们在添加拦截器的方法上指定了拦截的路径为/hello然后在拦截器的preHandle方法中读取被拦截的方法上的CrossOrigin注解判断当前请求的来源是否被允许。如果允许就设置响应头否则返回403 Forbidden状态码。这样我们就可以在方法级别上进行跨域请求的控制了。