本文介绍了Python Flask跨站点HTTP POST - 不适用于特定的允许的来源的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图让Flask正确处理跨站脚本。我已经从这里采取跨域装饰片段:
不被Access-Control-Allow-Origin允许。



除了origin ='*'之外,我无法得到它的工作。

有人有什么想法吗? / p>

以下是完整的代码:

  from datetime import timedelta 
from flask import make_response,request,current_app,Flask,jsonify从functools中获取
import update_wrapper
$ b $ def crossdomain(origin = None,methods = None,headers = None,
max_age = 21600,attach_to_all = True,
automatic_options = True):
如果方法不是无:
methods =','.join(对于方法中的x进行排序(x.upper() )
如果标题不是None和不是isinstance(headers,basestring):
headers =','.join(x.upper()for x in header)
if isinstance(origin,basestring):
origin ='如果isinstance(max_age,timedelta):
max_age = max_age.total_seconds()
$ b $ def get_methods():
如果方法是不是None:
返回方法
$ b $ options_resp = current_app.make_default_options_response()
return options_resp.headers ['allow']

def decorator(f) :
def wrapped_function(* args,** kwargs):
if auto_options and request.method =='OPTIONS':
resp = current_app.make_default_options_response()
else:
resp = make_response(f(* args,** kwargs))
如果不是attach_to_all和request.method!='OPTIONS':
return resp

h = resp .headers

h ['Access-Control-Allow-Origin'] =原点$ b $ ['Access-Control-Allow-Methods'] = get_methods()
h ['Access-Control-Max-Age'] = str (max_age)
如果header不是None:
h ['Access-Control-Allow-Headers'] = headers
return resp

f.provide_automatic_options = False
return update_wrapper(wrapped_function,f)
返回装饰器
$ b应用程序= Flask(__ name__)

app.route('/ my_service',methods = ['POST','OPTIONS'])
@crossdomain(origin ='*',headers ='Content-Type')
def my_service():
return jsonify(foo ='跨域ftw')

if __name__ =='__main__':
app.run(host =0.0.0.0,port = 8080,debug = True)

引用我的python版本是2.7.2
Flask版本是0.7.2

解决方案

我只是用pytho n版本2.7.3和Flask版本0.8。



在这些版本中, @crossdomain(origin ='myserver.com',headers ='Content-Type')

但它可以与

  @crossdomain(origin ='http://myserver.com',headers =' Content-Type')

也许这对Flask 0.7.2不起作用? (尽管它在片段页面上说了什么)。




编辑:
玩完这个之后, (并升级到Flask 0.9)似乎真正的问题(或另一个问题)可能与列表中有多个允许的起源有关。换句话说,使用上面这样的代码:

  @crossdomain(origin = ['http://myserver.com' ,'http://myserver2.com'],headers ='Content-Type')

doesn没有工作。

为了解决这个问题,我调整了装饰器。在此处查看代码:



如果代码位于列表中,则此代码仅返回请求站点的域。有点古怪,但至少对我来说,问题解决了:)

I'm trying to get Flask to handle cross-site scripting properly. I've taken the crossdomain decorator snippet from here:http://flask.pocoo.org/snippets/56/

In the code below, I've put the decorator snippet and the basic flask server.

I'm calling the decorator with headers='Content-Type' because otherwise I was getting "Request header field Content-Type is not allowed by Access-Control-Allow-Headers." in the browser.

So here is my question:As-is, the code below works. But when I want to restrict to only a specific server like so:

@crossdomain(origin='myserver.com', headers='Content-Type')

I get the browser error

"Origin http://myserver.com is not allowed by Access-Control-Allow-Origin."

I can't get it working for anything other than origin='*'.

Does anybody have any ideas?

Here is the complete code:

from datetime import timedelta
from flask import make_response, request, current_app, Flask, jsonify
from functools import update_wrapper

def crossdomain(origin=None, methods=None, headers=None,
            max_age=21600, attach_to_all=True,
            automatic_options=True):
    if methods is not None:
        methods = ', '.join(sorted(x.upper() for x in methods))
    if headers is not None and not isinstance(headers, basestring):
        headers = ', '.join(x.upper() for x in headers)
    if not isinstance(origin, basestring):
        origin = ', '.join(origin)
    if isinstance(max_age, timedelta):
        max_age = max_age.total_seconds()

    def get_methods():
        if methods is not None:
            return methods

        options_resp = current_app.make_default_options_response()
        return options_resp.headers['allow']

    def decorator(f):
        def wrapped_function(*args, **kwargs):
            if automatic_options and request.method == 'OPTIONS':
            resp = current_app.make_default_options_response()
            else:
                resp = make_response(f(*args, **kwargs))
            if not attach_to_all and request.method != 'OPTIONS':
                return resp

            h = resp.headers

            h['Access-Control-Allow-Origin'] = origin
            h['Access-Control-Allow-Methods'] = get_methods()
            h['Access-Control-Max-Age'] = str(max_age)
            if headers is not None:
                h['Access-Control-Allow-Headers'] = headers
            return resp

        f.provide_automatic_options = False
        return update_wrapper(wrapped_function, f)
    return decorator

app = Flask(__name__)

@app.route('/my_service', methods=['POST', 'OPTIONS'])
@crossdomain(origin='*', headers='Content-Type')
def my_service():
    return jsonify(foo='cross domain ftw')

if __name__ == '__main__':
    app.run(host="0.0.0.0", port=8080, debug=True)

For reference my python version is 2.7.2Flask version is 0.7.2

解决方案

I just tried the same code with python version 2.7.3 and Flask version 0.8.

With these versions, it fails with

@crossdomain(origin='myserver.com', headers='Content-Type')

but it works with

@crossdomain(origin='http://myserver.com', headers='Content-Type')

Perhaps it just doesn't work with Flask 0.7.2? (despite what it says on the snippet page).


EDIT:After playing with this a lot more (and upgrading to Flask 0.9) it seems that the real problem (or yet another problem) might be related to having multiple allowed origins in a list. In other words, using the above code like this:

@crossdomain(origin=['http://myserver.com', 'http://myserver2.com'], headers='Content-Type')

doesn't work.

To fix this problem I tweaked the decorator. See code here:http://chopapp.com/#351l7gc3

This code returns only the domain of the requesting site if it is in the list. Kinda quirky, but at least for me, problem solved :)

这篇关于Python Flask跨站点HTTP POST - 不适用于特定的允许的来源的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

11-02 22:13