CORS跨域请求

一、问题

  服务器端代码

from flask import Flask
from flask import make_response
from flask import jsonify

app = Flask(__name__)


def cors_response(res):
    response = make_response(jsonify(res))
    response.headers['Access-Control-Allow-Origin'] = '*'
    response.headers['Access-Control-Allow-Headers'] = 'content-type'
    return response


@app.route("/api/order", methods=['GET', 'POST', 'OPTIONS'])
def index():
    print('request success')
    return cors_response({'code': 0, 'data': 'success'})


if __name__ == '__main__':
    app.run()

  axios请求代码

axios.post('http://127.0.0.1:5000/api/order',
                    {headers: {'Content-type': 'application/json', 'Access-Control-Allow-Origin': '*'}}
                )

   运行结果

    服务器端控制台结果

    浏览器console控制台

二、CORS跨域原理

1.CORS简介

CORS需要浏览器和服务器同时支持。目前,所有浏览器都支持该功能,IE浏览器不能低于IE10。整个CORS通信过程,都是浏览器自动完成,不需要用户参与。对于开发者来说,CORS通信与同源的AJAX通信没有差别,代码完全一样。浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉。因此,实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨源通信。

2.两种请求

浏览器将CORS请求分成两类:简单请求(simple request)和非简单请求(not-so-simple request)。

只要同时满足以下两大条件,就属于简单请求。

(1) 请求方法是以下三种方法之一:

  • HEAD
  • GET
  • POST

(2)HTTP的头信息不超出以下几种字段:

  • Accept
  • Accept-Language
  • Content-Language
  • Last-Event-ID
  • Content-Type:只限于三个值application/x-www-form-urlencodedmultipart/form-datatext/plain

凡是不同时满足上面两个条件,就属于非简单请求。

浏览器对这两种请求的处理,是不一样的。

三、错误分析及解决

上述请求为非简单请求,请求过程

  1. 正式通信前,会有一次HTTP查询请求,称为‘预检’请求(preflight)。预检请求用的方法是OPTIONS,与控制台的结果符合
  2. 服务器接收预检请求后,通过检查origin,Access-Control-Request-MethodAccess-Control-Request-Headers字段以后,确认允许跨源请求,就可以做出回应。
    1. 检查origin:response headers中的Access-Control-Allow-Origin的值是否包含发送请求的域名。
      Access-Control-Allow-Origin: * 表示同意任意跨域请求
    2. 检查Access-Control-Request-Method:它的值是逗号分隔的一个字符串,表明服务器支持的所有跨域请求的方法,由于此次请求的方法是POST,服务器默认支持,因此不需要设置
    3. 如果浏览器请求包括Access-Control-Request-Headers字段,则Access-Control-Allow-Headers字段是必需的。它也是一个逗号分隔的字符串,表明服务器支持的所有头信息字段,不限于浏览器在"预检"中请求的字段。由于以上例子的浏览器请求添加了自定义的Access-Control-Allow-Origin字段,所以需要将服务器端的
      response.headers['Access-Control-Allow-Headers'] = 'content-type' 改为
      response.headers['Access-Control-Allow-Headers'] = 'content-type, Access-Control-AllowOrigin'

 参考:

跨域资源共享CORS详解

原文地址:https://www.cnblogs.com/xiaochengzi/p/9805236.html