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()

参考来源:

  1. 什么是跨域?跨域解决方法
  2. Access-Control-Allow-Credentials
  3. 慕尼黑的夜晚无繁华的评论
  4. [Tornado—添加请求头允许跨域请求访问](https://www.cnblogs.com/liuhaidon/p/12015044.html)
  5. tornado跨域的解决方法
  6. 阮一峰大佬的好文
posted @ 2020-08-21 16:08  小片清风  阅读(305)  评论(0编辑  收藏  举报