前言:
跨域问题 “Cross-Origin Resource Sharing (CORS)” 的本质是 浏览器禁止从一个源加载的脚本与另一个源进行交互,即 --- 浏览器的同源策略(Same-origin policy)他的定义是:
The same-origin policy is a critical security mechanism that restricts how a document or script loaded from one origin can interact with a resource from another origin. It helps to isolate potentially malicious documents, reducing possible attack vectors.
同源策略限制了从同一个源加载的文档或脚本如何与来自另一个源的资源进行交互。这是一个用于隔离潜在恶意文件的重要安全机制。
经过:
最近使用flask编写了一个前后端分离的web项目,前端对接时使用$.ajax,并且出现了如下问题:
解决思路:
我们已经知道出现跨域问题的核心原因是浏览器的同源策略,所以解决问题的思路有两个:
- 从浏览器端解决
- 从服务器端解决
这次先谈如何从服务端解决,但是想要解决这个问题我们就需要搞明白到底什么是同源:
同源的定义:
如果两个页面的协议,端口(如果有指定)和域名都相同,则两个页面具有相同的源。
下表给出了相对http://store.company.com/dir/page.html
同源检测的示例:
| URL | 结果 | 原因 |
| http://store.company.com/dir2/other.html
| 成功 | |
| http://store.company.com/dir/inner/another.html
| 成功 | |
| https://store.company.com/secure.html
| 失败 | 不同协议 ( https和http ) |
| http://store.company.com:81/dir/etc.html
| 失败 | 不同端口 ( 81和80) |
| http://news.company.com/dir/other.html
| 失败 | 不同域名 ( news和store ) |
另请参见文件的源定义: URLs.
解决方案
我们可以使用CORS的方式解决这个问题“Cross-Origin Resource Sharing (CORS)”
什么是CORS?
Cross-Origin Resource Sharing (CORS) is a mechanism that uses additional HTTP headers to tell a browser to let a web application running at one origin (domain) have permission to access selected resources from a server at a different origin. A web application makes a cross-origin HTTP request when it requests a resource that has a different origin (domain, protocol, and port) than its own origin.
跨源资源共享(CORS)是一种机制,它使用其他HTTP标头告诉浏览器让在一个源(域)上运行的Web应用程序有权从不同来源的服务器访问所选资源。Web应用程序在请求具有与其自己的源不同的源(域,协议和端口)的资源时,会发出跨源HTTP请求。
一个跨域请求的例子:JavaScript的Web应用程序代码所服务的前端http://domain-a.com
应用XMLHttpRequest
做出了要求http://api.domain-b.com/data.json
。
出于安全原因,浏览器会限制从脚本中发起的跨源HTTP请求。例如,XMLHttpRequest
与提取API遵循同源策略。这意味着使用这些API的Web应用程序只能从加载应用程序的同一源请求HTTP资源,除非来自其他来源的响应包含正确的CORS标头。
CORS机制支持浏览器和Web服务器之间的安全跨源请求和数据传输。现代浏览器在API容器(如FetchXMLHttpRequest
或Fetch)中使用CORS 来帮助降低跨源HTTP请求的风险。
如何在分flask中使用?
代码示例:
from flask_cors import *
app = Flask(__name__)
CORS(app, supports_credentials=True)
亦或者你可以使用装饰器的方式为指定的视图函数进行配置
@app.route("/")
@cross_origin()
def helloWorld():
return "Hello, cross-origin-world!"
flask中有随时可用的flask_cors 库,你可以直接调用他
以下是Flask-CORS 的官方文档链接
http://flask-cors.readthedocs.io/en/latest/
原理?
Functional overviewSection
The Cross-Origin Resource Sharing standard works by adding new HTTP headers that allow servers to describe the set of origins that are permitted to read that information using a web browser. Additionally, for HTTP request methods that can cause side-effects on server's data (in particular, for HTTP methods other than
GET
, or forPOST
usage with certain MIME types), the specification mandates that browsers "preflight" the request, soliciting supported methods from the server with an HTTPOPTIONS
request method, and then, upon "approval" from the server, sending the actual request with the actual HTTP request method. Servers can also notify clients whether "credentials" (including Cookies and HTTP Authentication data) should be sent with requests.
CORS failures result in errors, but for security reasons, specifics about what went wrong are not available to JavaScript code. All the code knows is that an error occurred. The only way to determine what specifically went wrong is to look at the browser's console for details.
Subsequent sections discuss scenarios, as well as provide a breakdown of the HTTP headers used.
跨源资源共享标准的工作原理是添加新的HTTP标头,允许服务器描述允许使用Web浏览器读取该信息的起源集。此外,对于可能对服务器数据产生副作用的HTTP请求方法(特别是对于除某些MIME类型以外的HTTP方法GET
或用于POST
某些MIME类型),规范要求浏览器“预检”请求,从而请求支持的方法。服务器使用HTTPOPTIONS
请求方法,然后,在服务器“批准”后,使用实际的HTTP请求方法发送实际请求。服务器还可以通知客户端是否“凭据”(包括Cookie) 和HTTP认证数据)应该与请求一起发送。CORS失败会导致错误,但出于安全原因,JavaScript代码无法使用有关错误的详细信息。所有代码都知道发生了错误。确定具体问题的唯一方法是查看浏览器的控制台以获取详细信息。
仓促整理,不喜勿喷