totnado前后端分离跨域设置
简介
跨域问题估计是所有web人员最容易,也几乎都会碰到的问题了。特别是在前后端分离这种架构中,跨域问题几乎是随处可见了。
为什么会出现跨域问题
为了安全,浏览器拥有一个同源策略限制。它是浏览器最为核心、也是最基本的安全功能。即同源策略会阻止一个域的js脚本和另外一个域的内容进行交互。谁也不想自己正刷购物网站的时候,一个别的网站脚本把购物车给你意见清空还顺便用你的钱付款了。
同源:两个页面具有相同的协议(protocol), 主机(host)和端口号(port)。
跨域示例
当一个请求url的协议、域名、端口三者之间任意一个与当前页面url不同即为跨域
当前页面url | 被请求页面url | 是否跨域 | 原因 |
---|---|---|---|
http://www.test.com/ | http://www.test.com/index.html | 否 | 同源(协议、域名、端口号相同) |
http://www.test.com/ | https://www.test.com/index.html | 跨域 | 协议不同(http/https) |
http://www.test.com/ | http://www.baidu.com/ | 跨域 | 主域名不同(test/baidu) |
http://www.test.com/ | http://blog.test.com/ | 跨域 | 子域名不同(www/blog) |
http://www.test.com:8080/ | http://www.test.com:7001/ | 跨域 | 端口号不同(8080/7001) |
解决办法
在web不断发展中,出现较多办法。可以参考这篇文章.
我们这里直接上目前通用的CORS(Cross-Origin Resource Sharing)方式,即跨域资源共享。它是 W3C 标准,属于跨源 AJAX 请求的根本解决方法。
1、普通跨域请求:只需服务器端设置Access-Control-Allow-Origin
2、带cookie跨域请求:前后端都需要进行设置
前端设置
Vue.http.options.credentials = true # 前端设置是否带 cookie
这里仅以 vue 为例。毕竟我是个后端。总之,就是 credentials 设置为 true。
后端设置
tornado
代码示例:
class BaseHandler(tornado.web.RequestHandler):
def __init__(self, *arg, **kwarg):
super(BaseHandler, self).__init__(*arg, **kwarg)
# 解决跨域问题
def set_default_headers(self, json_str):
origin = self.request.headers.get("Origin")
origin = '*' if not origin else origin
self.set_header("Access-Control-Allow-Origin", origin)
self.set_header("Access-Control-Allow-Headers", "x-requested-with")
self.set_header("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE") # 允许的请求类型
self.set_header("Access-Control-Allow-Credentials", "true")
self.set_header("Content-type", "application/json")
self.set_status(200)
self.write(json_str)
self.finish()
def send_json(self, data=None, errcode=200, errmsg='请求成功'):
if not data:
data = {}
res = {
'errcode': errcode,
'errmsg': errmsg
}
res.update(data)
self.send_str(json.dumps(res))
"""
当客户端发送非简单请求时,客户端会先发送一个带有询问性质的 options 预检请求,获取返回值来确认服务器是否支持这样的请求。
options 请求可以不做具体处理,但是必须要通过。
options 请求通过后,执行其他允许的请求。
"""
def options(self):
self.send_json()
参考来源: