对预检的响应没有通过访问控制检查

时间:2018-04-03 00:31:04

标签: python flask cors

我有一个简单的flask服务器

import pdb

from flask import Flask, jsonify, abort, make_response, request, send_from_directory
from flask_cors import CORS, cross_origin
from pprint import pprint

import argparse

from mylib.mylib_rest_api import ProcessRestApiRequest


DEBUG=True
app = Flask(__name__)
CORS(app)

parser = argparse.ArgumentParser(description='Run the server')

parser.add_argument('--ip-address', default='127.0.0.1', help='Server IP Address. Default: %(default)s')
parser.add_argument('--port', type=int, default=8081, help='Server port')

args = parser.parse_args()

@app.errorhandler(404)
def not_found(error):
    return make_response(jsonify({'error': 'Not found'}), 404)

def do_pre_serve_actions():
    if not request.json: abort(400)
    # Extract the data
    dictReq = request.get_json(force=True)
    if DEBUG:
        pprint('dictReq: '+str(dictReq))
    return dictReq

def do_post_serve_actions(dictResp):
    if DEBUG:
        pprint("dictResp: "+str(dictResp))
    dictJSONResp = jsonify(dictResp)
    objRespADF = make_response(dictJSONResp)
    return objRespADF

@app.route('/<target>', methods=['POST'])
def serve(target):
    dictReq = do_pre_serve_actions()
    dictResp = ProcessRestApiRequest(dictReq, target)
    return do_post_serve_actions(dictResp)

if __name__ == '__main__':
    app.run(debug=DEBUG, host=args.ip_address, port=args.port)

这是请求的样子:

makeRequestAndSendData(xhr, dict) {
    dict['Interface'] = this.getChipInterface();
    var data = JSON.stringify(dict);
    var url = this.server.getUrl();

    console.log("url: "+url);
    console.log("Request Dictionary:");
    console.log(dict);

    xhr.open("POST", url, true);
    xhr.setRequestHeader("Access-Control-Allow-Origin", "*");
    xhr.setRequestHeader("Access-Control-Allow-Headers","*");
    xhr.setRequestHeader("Access-Control-Allow-Credentials", "true");
    xhr.setRequestHeader("Content-type","application/json");
    xhr.send(data);
}

这是我得到的:

  

无法加载http://192.168.0.132:8084/mychip:对预检的响应   请求没有通过访问控制检查:   &#39;访问控制允许来源&#39;标头的值为&#39; null&#39;那不是   等于提供的原产地。起源&#39; null&#39;因此是不允许的   访问。

我做错了什么?我在网上随处可见,似乎它得到了我需要的一切。我错过了什么吗?

1 个答案:

答案 0 :(得分:0)

如果您从文件系统而不是网络提供页面,则可能会出现基于Chrome和WebKit / Chrome的浏览器(Opera,Brave等)。在这种情况下,没有原始网站(因为它是从文件提供的),Chrome会在预检OPTIONS请求中发送标头Origin: null。您启用CORS的Flask服务器将在其预检响应中回复此来源,但Chrome会将其拒绝为无效来源,即使这是Chrome首先发送的内容。

Firefox还会在OPTIONS请求中发送标头Origin: null,但是响应没问题,所以它会发出实际的POST请求。我还发现,从文件系统加载时,Android上的Chrome似乎有效。

作为解决方法,从HTTP服务器提供测试文件。最简单的方法(仅用于测试目的)是使用Python的SimpleHTTPSever。只需切换到包含测试HTML文件的目录,然后运行以下命令:

$ python -m SimpleHTTPServer

它将启动侦听端口8000的HTTP服务器,因此您可以使用URL http://localhost:8000/cors_test.html将文件加载到浏览器中。

另请注意,Access-Control-Allow-*标头应在预检响应中发送,而不是请求。 flask-cors通常会为您处理,而客户端XMLHttpRequest对象应该正确地为您构建请求。