路由以及跨域cors

一、跨域限制

在进行前后端联调的时候,可能会遇到下面这个报错:

Access to XMLHttpRequest at ‘http://127.0.0.1:5000/login’ from origin ‘http://localhost:8080’ 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.

这个错误就是跨域问题,是发生在浏览器端的。浏览器中有一个同源策略,它是一个安全策略,用来限制源的交互。

  • 同源策略:是一种约定,是浏览器核心,也是最基本的安全功能,它会阻止一个域的JS脚本和另一个域的内容进行交互。如果缺少了同源策略,浏览器很容易受到XSS、CSFR等攻击。所谓同源(即在同一个域)就是两个页面具有相同的协议(protocol)、主机(host)和端口号(port)。

  • 跨域:当一个请求URL的协议、域名、端口三者之间的任意一个与当前页面URL不同,即为跨域。

示例:

  1. 创建cors.py文件;

from flask import Flask, render_template

# 创建Flask应用程序实例
app = Flask(__name__)

# 定义路由和视图函数
@app.route("/hello")
def hello():
    return "Hello Flask"

@app.route("/cors")
def cors():
    return render_template("cors.html")

if __name__ == '__main__':
    app.run(port=5050, debug=True)
  1. templates 目录下创建 cors.html;
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge"/>
    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
    <title>跨域问题示例</title>
</head>
<body>
    <div>
      <button class="button" id="hello">点我点我</button>
    </div>
</body>
</html>
<script type="text/javascript">
    var btnHello = document.querySelector("button#hello");
    btnHello.onclick = () => {
      var xhr = new XMLHttpRequest();
      xhr.onreadystatechange = function () {
        if (xhr.readyState == 4 && xhr.status == 200) {
          alert(xhr.responseText);
        }
      };
      xhr.withCredentials = true;
      xhr.open("get", "http://localhost:5050/hello", true);
      xhr.setRequestHeader("Content-Type", "text");
      xhr.send();
    };
</script>
  1. 启动后端服务后,去访问前端页面,当点击按钮的时候,可以看到控制台报错:

二、解决跨域问题

cors是一个w3c的标准,全称跨域资源共享,允许浏览器向跨域服务器发出请求。

  • 安装flask-cors :pip install flask-cors
  • 解决跨域问题分为两种:
    • 针对全局所有的API:CORS(app)
    • 针对特定的API:@cross_origin()

第一种方法:全局解决跨域问题

from flask import Flask, render_template
from flask_cors import CORS

# 创建Flask应用程序实例
app = Flask(__name__)
# 第一种方法:全局解决跨域问题
CORS(app, supports_credentials=True)


# 定义路由和视图函数
@app.route("/hello")
def hello():
    return "Hello Flask"

@app.route("/cors")
def cors():
    return render_template("cors.html")

if __name__ == '__main__':
    app.run(port=5050, debug=True)

第二种方式:局部解决跨域问题(老师不推荐,未作讲解)

另外,还可以结合蓝图去使用:

from flask import Flask, render_template, Blueprint
from flask_cors import CORS

# 创建Flask应用程序实例
app = Flask(__name__)

hello_route = Blueprint("hello", __name__, url_prefix="/hello")

CORS(app, supports_credentials=True)

# 定义路由和视图函数
@hello_route.route("")
def hello():
    return "Hello Flask"

@app.route("/cors")
def cors():
    return render_template("cors.html")

if __name__ == '__main__':
    app.register_blueprint(hello_route)
    app.run(port=5050, debug=True)