CORS解释:跨域资源共享在Web开发中的重要性
想知道什么是CORS (跨域资源共享)?
在间谍电影中,安全机构之间有一种编码的方式来进行信息传递。由于他们大多数情况下传递的信息如果落入敌人手中可能会被用来对付他们,所以他们必须确保接收信息的人是可信的。同样的原则也适用于发送信息的人。当发送者和接收者都是可信的时候,信息的可靠性和安全性可以得到保证。
浏览器和Web服务器之间的通信中发生了一个类似的情景,它被称为同源策略。
什么是同源策略?
你是否注意到网页无法访问来自其他网站的资源?这是因为同源策略的存在,它是Web浏览器中的一项安全功能,阻止网页从与其所服务的页面不同的域访问资源(如cookie、脚本和其他数据)。
一个源由URL的协议、域名和端口号的组合定义。大多数浏览器,包括Chrome、Firefox、Safari和Edge,都实施了同源策略来保护您的数据安全。
那么,为什么我们需要这个策略呢?为了理解这一点,让我们来看看互联网是如何工作的。当你访问一个网站时,你的浏览器向该网站发送一个请求,服务器通过发送所需的资源来回应。这些资源可能包括HTML、CSS、JavaScript和图片。
想象一下,一个网页也可以向其他域名发出请求。继续以我们的间谍电影为背景,来自另一个机构的秘密特工想要与不同组织或国家的特工取得联系,请求访问并共享信息。如果他们获得这个机会,就会给后者带来巨大的安全漏洞。他们可以窃取敏感信息并潜在地对其造成伤害。
同源策略的存在正是为了解决这个问题。尽管有关同源策略的一些误解,它并不意味着您不能从不同的源加载资源或将信息发送到另一个源。
然而,同源策略制定了限制访问和交互的规则,比如脚本、CSS、iframe、图像和视频。它就像一名保安,将网页限制在自己的域中,阻止它们访问其他域的资源。
这样可以保护您免受可能窃取您数据或诱使您执行不需要的操作的恶意攻击。
CORS是什么?
在现实生活中,当安全机构规定通信只能在内部进行以确保安全时,与同源策略类似。然而,可能会有情况他们需要与外界进行互动。或者与其他安全部门的特工进行沟通,为了实现这一点,他们可以实施另一种安全措施来验证这些特工。这种验证可以通过不同的方式进行,具体取决于涉及的特工。在互联网通信的情况下,CORS是使浏览器能够访问原本无法访问的资源(因为资源属于不同的源)的机制。
跨域资源共享(CORS)是一种使用额外的HTTP头部告诉浏览器,让一个源中运行的Web应用程序访问来自不同源的选定资源的机制。
我已经多次谈到了源,你可能想知道这是什么意思。源由URL的协议、域和端口定义。当你的API在一个源(如https://api.yaoweibin.com:3001)中,你的前端在https://yaoweibin.cn上时,这些源被认为是不同的。在这种情况下,你需要CORS来能够访问两端的资源。
当向服务器发送请求时,浏览器(客户端)和服务器发送请求和响应,HTTP头部被包含在其中。在这些头部中,还包含了其他头部来防止浏览器阻止通信。
为什么浏览器会阻止通信?
这是浏览器的安全特性。当请求来自与客户端不同的源时,它会阻止通信。CORS包含的其他头部是告诉客户端可以使用接收到的响应的一种方式。
CORS的常见问题
作为Web开发人员,你需要访问来自不同域的资源 – 就像构建一个使用多个来源的的Web应用程序一样。你可以实现CORS,它允许Web服务器指定哪些其他域可以访问它们的资源,这样你仍然可以构建你想要的Web应用程序。这个行为是在服务器端实现的,所以不能在客户端重新配置。
如果你遇到CORS错误,这意味着服务器拒绝了你从不同域访问其资源的请求,因为它不符合所需的安全标准。
如果服务器没有正确设置,就会发生这种情况。但不要担心 – 有一种简单的方法可以解决它。只需确保Access-Control-Allow-Origin头部正确配置。这告诉服务器允许哪些域访问其资源,如果没有正确设置,可能会遇到问题。
下面是一些可能遇到的其他问题:
- 如果你试图在跨域资源共享请求中使用一个链接(如DELETE或PUT),重要的是要确保服务器允许它。默认情况下,浏览器只允许简单的方法,所以如果你想使用其他方法,需要明确设置Access-Control-Allow-Methods头部。
- 此外,进行此类请求时,你需要小心从浏览器发送的凭据(如cookie或授权头部),服务器是否允许。
- 此外,如果“预检”查询(如具有自定义头部的查询)显示不支持,则服务器不会正确响应。
- 如果Web页面尝试从不同域访问资源(托管在一个链接中),如图像、脚本或样式表,托管资源的服务器可能不允许来自页面托管域的请求。
幸运的是,有几种方法可以解决这个问题。一种解决方案是通过发送适当的头部配置服务器以允许跨域请求。
另一种选择是使用代理服务器代表你的Web应用程序发出请求,或者使用JSON-P将响应包装在回调函数中。
此外,还有一些库可以简化客户端上的跨域请求,处理头部并提供无问题的请求API。
通过尝试这些不同的解决方案,你可以解决这些问题,并确保你的Web应用程序可以访问其所需的资源以正常运行。
警告 – 这些技术可能会带来自己的安全风险,所以使用它们时要小心!
CORS头部
其中一个是响应或请求头部。
响应头部
这些是服务器在其响应中发送回来的头部。
Access-Control-Allow-Origin:
: 这用于指定允许访问服务器资源的来源。可以指定只允许来自特定来源的请求 –Access-Control-Allow-Origin: https://yaoweibin.cn
,或者指定来源不重要 –Access-Control-Allow-Origin: *
。Access-Control-Expose-Headers:
: 正如其名称所示,这列出了浏览器可以访问的标头。Access-Control-Max-Age:
: 这表示预检请求的响应可以被缓存的持续时间。Access-Control-Allow-Credentials:
: 这表示当初始请求使用凭证进行时,浏览器可以使用响应。Access-Control-Allow-Methods:
: 这表示在尝试访问资源时允许的方法。Access-Control-Allow-Headers:
: 这表示可以在请求中使用的HTTP标头。
下面是响应的示例
HTTP/1.1 204 No Content
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET,HEAD,PUT,PATCH,POST,DELETE
Vary: Access-Control-Request-Headers
Access-Control-Allow-Headers: Content-Type, Accept
Content-Length: 0
Date: Sat, 16 Nov 2019 11:41:08 GMT+1
Connection: keep-alive
请求标头
以下是客户端请求应包含的标头,以便利用CORS机制。
Origin:
: 这表示客户端请求的来源。当使用前端和后端一起工作时,如前面所述,这将是您前端应用程序的主机。Access-Control-Request-Method:
: 这在预检请求中用于指示将用于进行请求的HTTP方法。Access-Control-Request-Headers:
: 这在预检请求中用于指示将用于进行请求的HTTP标头。
下面是请求的示例
curl -i -X OPTIONS localhost:3001/api
-H 'Access-Control-Request-Method: GET'
-H 'Access-Control-Request-Headers: Content-Type, Accept'
-H 'Origin: http://localhost:3000'
预检请求
在这里提到预检请求时,它可能意味着什么呢?
当客户端在主请求之前必须发送预检请求时,预检请求发生。预检请求更像是一个探针,用于确定服务器是否支持即将进行的主请求。当获得肯定确认时,然后发送主请求。
如果请求不是预检请求,则称为简单请求。
实现CORS
您主要会希望在应用程序的后端设置一些东西。实现取决于您使用的框架。在本教程中,我们将看一下如何在NodeJS和Rails中实现。
Rails
我建议您使用rack-cors gem。然后,您需要将以下内容添加到config/application.rb
文件中。
config.middleware.insert_before 0, Rack::Cors do
allow do
origins '*'
resource '*',
headers: :any,
expose: %i(access-token expiry token-type uid client),
methods: %i(get post put patch delete options head),
credentials: true
end
end
NodeJS
在Node.js中,代码如下。
在代码片段中,我们设置了允许访问我们服务器上可用资源的来源、方法、标头和凭据。要在Apache或Nginx中实施,请参阅此guide。
结论
CORS放宽了策略,以便您的浏览器可以访问您希望它访问的资源。了解它是什么,为什么它很重要以及如何设置它将有助于解决构建Web应用程序时可能遇到的问题。