-
CORS
2020-09-29 15:23:00CORS CORS 是一个 W3C 标准,全称是"跨域资源共享" Cross-origin resource sharing 。 出于安全的考虑, 浏览器不允许 Ajax 调用当前源之外的资源. 即浏览器的同源策略。而 CORS 允许浏览器向跨源服务器,发出...CORS
CORS 是一个 W3C 标准,全称是"跨域资源共享" Cross-origin resource sharing 。
出于安全的考虑, 浏览器不允许 Ajax 调用当前源之外的资源. 即浏览器的同源策略。而 CORS 允许浏览器向跨源服务器,发出XMLHttpRequest请求,很明显 CORS 就是为了解决跨域问题而诞生的 。
CORS 需要浏览器和服务器同时支持。目前,所有主流浏览器都支持该功能,IE 浏览器不能低于 IE10。在浏览器端, 整个 CORS 通信过程,都是浏览器自动完成,不需要用户参与。对于开发者来说,CORS 通信与同源的 AJAX 通信没有差别,代码完全一样。浏览器一旦发现 AJAX 请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,用户对这些都不会有感觉。因此,实现 CORS 通信的关键是服务器。CORS与JSONP的使用目的相同,但是比JSONP更强大。
JSONP只支持GET请求,CORS支持所有类型的HTTP请求。JSONP的优势在于支持老式浏览器,以及可以向不支持CORS的网站请求数据。跨域请求分类
浏览器将跨域请求分为两大类: 简单请求和非简单请求.
同时满足以下两个条件的请求都为简单请求:
一、请求方式为下列之一:
- GET
- POST
- HEAD
二、请求头信息不超出以下字段:
-
List item
-
Accept
-
Accept-Language
-
Content-Language
-
Content-Type:只限于三个值
application/x-www-form-urlencode
multipart/form-data
xext/plain
跨域请求处理方式
简单请求
对于简单请求,浏览器直接发出CORS请求。具体来说,就是在头信息之中,增加一个Origin字段。
下面是一个例子,浏览器发现这次跨源AJAX请求是简单请求,就自动在头信息之中,添加一个Origin字段。GET /cors HTTP/1.1 Origin: http://api.bob.com Host: api.alice.com Accept-Language: en-US Connection: keep-alive User-Agent: Mozilla/5.0...
对于简单请求, 浏览器直接发出CORS请求, 即浏览器自动在请求header中加上Origin字段, 告诉服务器这个请求来自哪个源(请求协议+域名+端口). 服务器收到请求后, 会对比这个字段, 如果字段值不在服务器的许可范围内, 服务器会返回一个正常的HTTP响应, 但是其响应头中不会包含Access-Control-Allow-Origin字段, 浏览器发现后, 就会抛出一个异常提示响应头中没有这个字段. 如果这个源在服务器的许可范围内, 服务器的响应头会加上以下字段:
Access-Control-Allow-Origin: http://api.bob.com Access-Control-Allow-Credentials: true Access-Control-Expose-Headers: FooBar Content-Type: text/html; charset=utf-8
上面的头信息之中,有三个与CORS请求相关的字段,都以Access-Control-开头。
(1)Access-Control-Allow-Origin
该字段是必须的。它的值要么是请求时Origin字段的值,要么是一个*,表示接受任意域名的请求。
(2)Access-Control-Allow-Credentials
该字段可选。它的值是一个布尔值,表示是否允许发送Cookie。默认情况下,Cookie不包括在CORS请求之中。设为true,即表示服务器明确许可,Cookie可以包含在请求中,一起发给服务器。这个值也只能设为true,如果服务器不要浏览器发送Cookie,删除该字段即可。
(3)Access-Control-Expose-Headers
该字段可选。CORS请求时,XMLHttpRequest对象的getResponseHeader()方法只能拿到6个基本字段:Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma。如果想拿到其他字段,就必须在Access-Control-Expose-Headers里面指定。上面的例子指定,getResponseHeader(‘FooBar’)可以返回FooBar字段的值。
withCredentials 属性
上面说到,CORS请求默认不发送Cookie和HTTP认证信息。如果要把Cookie发到服务器,一方面要服务器同意,指定Access-Control-Allow-Credentials字段。Access-Control-Allow-Credentials: true
另一方面,开发者必须在AJAX请求中打开withCredentials属性。
var xhr = new XMLHttpRequest(); xhr.withCredentials = true;
否则,即使服务器同意发送Cookie,浏览器也不会发送。或者,服务器要求设置Cookie,浏览器也不会处理。
但是,如果省略withCredentials设置,有的浏览器还是会一起发送Cookie。这时,可以显式关闭withCredentials。xhr.withCredentials = false;
需要注意的是,如果要发送Cookie,Access-Control-Allow-Origin就不能设为星号,必须指定明确的、与请求网页一致的域名。同时,Cookie依然遵循同源政策,只有用服务器域名设置的Cookie才会上传,其他域名的Cookie并不会上传,且(跨源)原网页代码中的document.cookie也无法读取服务器域名下的Cookie。
非简单请求
预检请求
非简单请求是那种对服务器有特殊要求的请求,比如请求方法是PUT或DELETE,或者Content-Type字段的类型是application/json。非简单请求的CORS请求,会在正式通信之前,增加一次HTTP查询请求,称为"预检"请求(preflight)。
浏览器先询问服务器,当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些HTTP动词和头信息字段。只有得到肯定答复,浏览器才会发出正式的XMLHttpRequest请求,否则就报错。
下面是一段浏览器的JavaScript脚本。
var url = 'http://api.alice.com/cors'; var xhr = new XMLHttpRequest(); xhr.open('PUT', url, true); xhr.setRequestHeader('X-Custom-Header', 'value'); xhr.send();
上面代码中,HTTP请求的方法是PUT,并且发送一个自定义头信息X-Custom-Header。
浏览器发现,这是一个非简单请求,就自动发出一个"预检"请求,要求服务器确认可以这样请求。下面是这个"预检"请求的HTTP头信息。
OPTIONS /cors HTTP/1.1 Origin: http://api.bob.com Access-Control-Request-Method: PUT Access-Control-Request-Headers: X-Custom-Header Host: api.alice.com Accept-Language: en-US Connection: keep-alive User-Agent: Mozilla/5.0...
"预检"请求用的请求方法是OPTIONS,表示这个请求是用来询问的。头信息里面,关键字段是Origin,表示请求来自哪个源。
除了Origin字段,"预检"请求的头信息包括两个特殊字段。
- Access-Control-Request-Method
该字段是必须的,用来列出浏览器的CORS请求会用到哪些HTTP方法,上例是PUT。
- Access-Control-Request-Headers
该字段是一个逗号分隔的字符串,指定浏览器CORS请求会额外发送的头信息字段,上例是X-Custom-Header。
预检请求的回应
服务器收到"预检"请求以后,检查了Origin、Access-Control-Request-Method和Access-Control-Request-Headers字段以后,确认允许跨源请求,就可以做出回应。HTTP/1.1 200 OK Date: Mon, 01 Dec 2008 01:15:39 GMT Server: Apache/2.0.61 (Unix) Access-Control-Allow-Origin: http://api.bob.com Access-Control-Allow-Methods: GET, POST, PUT Access-Control-Allow-Headers: X-Custom-Header Content-Type: text/html; charset=utf-8 Content-Encoding: gzip Content-Length: 0 Keep-Alive: timeout=2, max=100 Connection: Keep-Alive Content-Type: text/plain
上面的HTTP回应中,关键的是Access-Control-Allow-Origin字段,表示http://api.bob.com可以请求数据。该字段也可以设为星号,表示同意任意跨源请求。
Access-Control-Allow-Origin: *
如果服务器否定了"预检"请求,会返回一个正常的HTTP回应,但是没有任何CORS相关的头信息字段。这时,浏览器就会认定,服务器不同意预检请求,因此触发一个错误,被XMLHttpRequest对象的onerror回调函数捕获。控制台会打印出如下的报错信息。
XMLHttpRequest cannot load http://api.alice.com. Origin http://api.bob.com is not allowed by Access-Control-Allow-Origin.
服务器回应的其他CORS相关字段如下。
Access-Control-Allow-Methods: GET, POST, PUT Access-Control-Allow-Headers: X-Custom-Header Access-Control-Allow-Credentials: true Access-Control-Max-Age: 1728000
(1)Access-Control-Allow-Methods
该字段必需,它的值是逗号分隔的一个字符串,表明服务器支持的所有跨域请求的方法。注意,返回的是所有支持的方法,而不单是浏览器请求的那个方法。这是为了避免多次"预检"请求。
(2)Access-Control-Allow-Headers
如果浏览器请求包括Access-Control-Request-Headers字段,则Access-Control-Allow-Headers字段是必需的。它也是一个逗号分隔的字符串,表明服务器支持的所有头信息字段,不限于浏览器在"预检"中请求的字段。
(3)Access-Control-Allow-Credentials
该字段与简单请求时的含义相同。
(4)Access-Control-Max-Age
该字段可选,用来指定本次预检请求的有效期,单位为秒。上面结果中,有效期是20天(1728000秒),即允许缓存该条回应1728000秒(即20天),在此期间,不用发出另一条预检请求。
浏览器的正常请求和回应
一旦服务器通过了"预检"请求,以后每次浏览器正常的CORS请求,就都跟简单请求一样,会有一个Origin头信息字段。服务器的回应,也都会有一个Access-Control-Allow-Origin头信息字段。
下面是"预检"请求之后,浏览器的正常CORS请求。
PUT /cors HTTP/1.1 Origin: http://api.bob.com Host: api.alice.com X-Custom-Header: value Accept-Language: en-US Connection: keep-alive User-Agent: Mozilla/5.0...
上面头信息的Origin字段是浏览器自动添加的。
下面是服务器正常的回应。
Access-Control-Allow-Origin: http://api.bob.com Content-Type: text/html; charset=utf-8
上面头信息中,Access-Control-Allow-Origin字段是每次回应都必定包含的。
-
跨域问题Access to XMLHttpRequest‘*‘from origin ‘*‘ has been blocked by CORS..Access-Control-...
2019-03-02 16:34:48跨域问题解决方案:CORS Access to XMLHttpRequest at '*' from origin '*' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-...跨域问题解决方案:CORS
Access to XMLHttpRequest at '*' from origin '*' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
从源'本地路径'访问 '目标路径(请求链接)'文本传输请求已被CORS策略阻塞:对预置请求的响应未通过访问控制检查:请求的资源上不存在'Access- control - allow - origin '报头。
错误原因:
本地路径和目标路径不是同一个域名下引起的跨域问题,并且,就算两个域名是同一个一级域名不同二级域名的时候,例如 a.baidu.com 和 b.baidu.com 是属于不同域的,也是会出现这个问题
介绍
出于安全原因,浏览器限制从脚本内发起的跨源HTTP请求。 例如,XMLHttpRequest和Fetch API遵循同源策略。 这意味着使用这些API的Web应用程序只能从加载应用程序的同一个域请求HTTP资源,除非响应报文包含了正确CORS响应头。
(注:这段描述不准确,并不一定是浏览器限制了发起跨站请求,也可能是跨站请求可以正常发起,但是返回结果被浏览器拦截了。)
CORS(跨源资源共享)是一个系统,由传输HTTP标头组成,用于确定浏览器是否阻止前端JavaScript代码访问跨源请求的响应
该同源安全政策禁止以资源跨域访问。但CORS使Web服务器能够表示他们希望选择允许跨资源访问其资源。
跨域资源共享(CORS) 是一种机制,它使用额外的 HTTP 头来告诉浏览器 让运行在一个 origin (domain) 上的Web应用被准许访问来自不同源服务器上的指定的资源。当一个资源从与该资源本身所在的服务器不同的域、协议或端口请求一个资源时,资源会发起一个跨域 HTTP 请求。
比如,站点 http://domain-a.com 的某 HTML 页面通过 <img> 的 src 请求 http://domain-b.com/image.jpg。网络上的许多页面都会加载来自不同域的CSS样式表,图像和脚本等资源。
跨域资源共享( CORS )机制允许 Web 应用服务器进行跨域访问控制,从而使跨域数据传输得以安全进行。现代浏览器支持在 API 容器中(例如
XMLHttpRequest
或 Fetch )使用 CORS,以降低跨域 HTTP 请求所带来的风险。解决方案:
1、如果跨域请求发生在相同一级域名不同二级域名之间
例如:a.baidu.com 和 b.baidu.com
跨域直接在邀请求的接口页面中强制设置域为一级域 document.domain = "baidu.com";
2、设置接口允许ajax跨域访问
在服务器aspx页面头文件里加:
<meta http-equiv="Access-Control-Allow-Origin" content="*" />
在web.config文件中的 system.webServer 节点下 增加如下配置
<system.webServer> <httpProtocol> <customHeaders> <add name="Access-Control-Allow-Methods" value="OPTIONS,POST,GET"/> <add name="Access-Control-Allow-Headers" value="x-requested-with"/> <add name="Access-Control-Allow-Origin" value="*" /> </customHeaders> </httpProtocol> </system.webServer>
网上说的解决方案都是Internet Explorer 8 、9使用 XDomainRequest 对象实现CORS。是不是有这么复杂?于是博主各种百度寻找解决方案。最后发现在调用处指定 jQuery.support.cors = true; 这一句就能解决IE8、9的问题了
这句话的意思就是指定浏览器支持跨域。IE9以上版本的浏览器、谷歌、火狐等都默认支持跨域,而IE8、9却默认不支持跨域,需要我们指定一下。
//例如 jQuery.support.cors = true; var ApiUrl = "http://b.baidu.com"; $(function () { $.ajax({ type: "get", url: ApiUrl + "api/Charging/GetAllChargingData", data: {}, success: function (data, status) { if (status == "success") { alert("ok"); } }, error: function (e) { alert("error"); }, complete: function () { } }); });
注:我这里设置的*是任意的请求都可以访问,如果需要限制替换成自己的访问地址就可以了。
参考资料:
HTTP访问控制(CORS) https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_CORS
CORS(跨源资源共享) https://developer.mozilla.org/en-US/docs/Glossary/CORS
你有困难我帮忙,我住隔壁我姓王。----------------- 你隔壁的老王宣。
-
跨域问题(CORS / Access-Control-Allow-Origin)
2018-11-24 23:11:50最近在项目中,调用Eureka REST接口时,出现了CORS跨越问题(Cross-origin resource sharing),在此与大家进行分享,避免多走些弯路。 项目前端(http://localhost:9000)通过Ajax方式调用Eureka REST 接口...1、前言
最近在项目中,调用Eureka REST接口时,出现了CORS跨越问题(Cross-origin resource sharing),在此与大家进行分享,避免多走些弯路。
项目前端(http://localhost:9000)通过Ajax方式调用Eureka REST 接口(http://localhost:8761/eureka/apps)时,却没有任何反应,则通过F12查看日志发现出现“Access-Control-Allow-Origin“类 异常,详细如下:
…… http://localhost:8761/eureka/apps. Origin http://localhost:9000 is not allowed by Access-Control-Allow-Origin……
通过google,发现是由于CORS跨越问题造成的,解决办法无非有两种方式:响应头添加参数和添加过滤器,下面就详细说说CORS跨越问题的起因与详细解决办法。
2、CORS
CORS,常被大家称之为跨越问题,准确的叫法是跨域资源共享(CORS,Cross-origin resource sharing),是W3C标准,是一种机制,它使用额外的HTTP头来告诉浏览器 让运行在一个 origin (domain) 上的Web应用被准许访问来自不同源服务器上的指定的资源。当一个资源从与该资源本身所在的服务器不同的域或端口请求一个资源时,资源会发起一个跨域 HTTP 请求。
http://localhost:9000请求http://localhost:8761/eureka/apps就是违背了上述原则,即:请求服务器不同端口的另一个资源,出于安全原因,浏览器限制发起的跨源HTTP请求,则会出现本文开头提到的现象及异常。
例如,XMLHttpRequest和Fetch API遵循同源策略, 这意味着使用这些API的Web应用程序只能从加载应用程序的同一个域请求HTTP资源,除非使用CORS头。
跨域资源共享( CORS )机制允许 Web 应用服务器进行跨域访问控制,从而使跨域数据传输得以安全进行。浏览器支持在 API 容器中(例如
XMLHttpRequest
或 Fetch )使用 CORS,以降低跨域 HTTP 请求所带来的风险。什么情况下存在跨域问题
- 本文提到的由 XMLHttpRequest 或 Fetch 发起的跨域 HTTP 请求。
- Web 字体 (CSS 中通过 @font-face 使用跨域字体资源),,因此,网站就可以发布 TrueType 字体资源,并只允许已授权网站进行跨站调用。
- WebGL 贴图。
- 使用 drawImage 将 Images/video 画面绘制到 canvas
- 样式表(使用 CSSOM)。
面对CORS的限制,将如何解决呢
世间万物完事,有因必有果,有果必有因。当然CORS的限制,官方也是给出了解决办法的。
CORS标准新增了一组 HTTP 头字段(Access-Control-Allow-Origin),允许服务器声明哪些源通过浏览器有权限访问哪些资源。另外,规范要求,对那些可能对服务器数据产生副作用的 HTTP 请求方法(特别是 GET以外的 HTTP 请求,或者搭配某些 MIME 类型的 POST请求),浏览器必须首先使用
OPTIONS
方法发起一个预检请求(preflight request),从而获知服务端是否允许该跨域请求。服务器确认允许之后,才发起实际的 HTTP 请求。在预检请求的返回中,服务器端也可以通知客户端,是否需要携带身份凭证(包括Cookies 和 HTTP 认证相关数据)。CORS请求失败会产生错误,但是为了安全,在JavaScript代码层面是无法获知到底具体是哪里出了问题。你只能查看浏览器的控制台以得知具体是哪里出现了错误。
如果有兴趣了解该机制剖析的可以参考https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
3、解决办法
在查阅大量资源,并了解过CORS机制后,解决办法实质必定会围绕Access-Control-Allow-Origin头。
解决办法如下:
添加响应头
在被请求资源中添加响应头信息"Access-Control-Allow-Origin:*
过滤器
在本项目中添加如下过滤器:
/** * 解决跨域问题 */ public class AccessControlAllowOriginFilter implements Filter { public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { HttpServletResponse response = (HttpServletResponse) res; response.setHeader("Access-Control-Allow-Origin", "*"); response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE"); response.setHeader("Access-Control-Allow-Credentials", "true"); chain.doFilter(req, response); } public void init(FilterConfig filterConfig) { } public void destroy() { } }
注解方式
在Spring Boot中拥有大量的注解,针对跨域问题,也提供了对应的注解@CrossOrigin,使用方法如下:
import java.util.HashMap; import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; /** * @author xcbeyond */ @RestController @RequestMapping(value = "/api", method = RequestMethod.POST) public class DemoController { @CrossOrigin(origins = "*") @RequestMapping(value = "/get") public String get() { …… } }
个人比较推荐使用上述的三种方式之一,其他方式请自己百度、谷歌吧
-
express 的cors跨域 cors
2018-08-13 16:13:10在express中写测试接口的时候,经常要考虑跨域,express有一个npm模块,使用起来非常方便cors。 npm i cors -D const express = require('express'); const cors = require('cors'); const app = express(); app....在express中写测试接口的时候,经常要考虑跨域,express有一个npm模块,使用起来非常方便
cors
。npm i cors -D const express = require('express'); const cors = require('cors'); const app = express(); app.use(cors());
-
Cors timing
2020-12-02 01:27:03<div><p>cors: use i18n system for changeable strings <p>cors: remove dead code <p>Fix timing issue for slow connections If the conenction was slow you could enabble cors and change options, but cors ... -
CORS Support
2020-12-01 11:45:42<div><ul><li>Create a CORS extension for WebServer to simplify CORS configuration and handling for users.</li><li>Document CORS with SE.</li><li>See ...oracle/helidon</p></div> -
CORS support
2021-01-12 06:15:18m having trouble figuring out an appropriate pattern for including CORS support. My use-case is that I am connecting a React app to an ASGI backend that uses Starlette's routing and response ... -
CORS跨域
2020-12-24 22:16:46CORS跨域 CORS:全称"跨域资源共享"(Cross-origin resource sharing)。 CORS需要浏览器和服务器同时支持,才可以实现跨域请求,目前几乎所有浏览器都支持CORS,IE则不能低于IE10。CORS的整个过程都由浏览器自动... -
cors.php into fruitcake/laravel-cors config override app cors.php
2020-12-08 18:59:40<div><h3>Description: <p><code>cors.php</code> into <code>fruitcake/laravel-cors</code> override <code>cors.php</code> which is located in the <code>var/app/ship/configs</code>, if place <code>cors.... -
Egg Cors
2020-05-26 09:21:11Egg.js跨域访问需使用egg-cors插件,典型的应用场景是前后端分离的项目中,前端与后台在不同的域下,此时若前端通过AJAX访问后端接口,此时就首先解决跨域问题。 安装egg-cors插件 $ npm i -S egg-cors 开启egg-... -
cors java 安全问题_CORS账号常见问题解答——CORS账号的全国CORS站差分源分享
2021-01-08 18:22:23现在市面上越来越流行网络RTK,也就是本文所要讲的单机站cors站差分模式。cors账号的连接信息包括IP、端口、源节点、用户名、密码,客户作业有几台RTK,就可以开通几个cors账号进行使用。需要注意的是,千寻cors虽然... -
CORS理解
2020-07-21 15:47:581. CORS cross-origin resource sharing, 跨域资源共享. 因为出于安全的考虑, 浏览器不允许Ajax调用当前源之外的资源. 即浏览器的同源策略. CORS需要浏览器和服务器同时支持。目前,所有主流浏览器都支持该功能,IE... -
CORS漏洞
2019-09-20 17:10:11CORS简介 什么是CORS? CORS是一个w3c标准、全称是"跨域资源共享"(Cross-origin resource sharing) 因为出于安全的考虑, 浏览器不允许Ajax调用当前源之外的资源.,即浏览器的同源策略 但一个请求url的协议、... -
跨域CORS
2019-01-28 15:33:32CORS是W3C标准。全场跨域资源共享(Cross-origin resourse sharing) 她允许浏览器向跨域资源服务器放出XMLHttpRequest请求,克服了AJAX只能同源使用的限制 1,CORS通信是浏览器自动完成的,不需要用户参与。CORS...
-
Android 其他问题点
-
Python中__new__和__init__的区别与联系
-
shotcut-win64-201128
-
Hadoop3.2.1 【 YARN 】源码分析 : ApplicationMasterLauncher
-
Metabase从入门到精通视频教程
-
【数据分析-随到随学】Mysql数据库
-
IEEE 802.3cn-2019 - IEEE Standard for Ethernet - Amendment 4
-
【2021】Python3+Selenium3自动化测试(不含框架)
-
火绒安全软件 v5.0.49.1
-
pyechart数据可视化
-
超类object
-
2020-10-18-kali搭建DVWA.md
-
Selenium3分布式与虚拟化
-
Restarant_class_Addmodel.py
-
JavaEE框架(Maven+SSM)全程实战开发教程(源码+讲义)
-
解决页面滚动并滚动停止时间问题案例
-
SQL Server 2016 高可用灾备技术合集
-
scratch demo.7z
-
Scratch编程等级考试二级真题讲解(电子学会图形化编程)
-
第1章 Java入门基础及环境搭建【java编程进阶】