IPアドレスを変更する可能性のある少数のクライアントからのPUT要求を受け入れるREST Restfulの小さな書き込み専用Flask apiを開発しました。私のクライアントは、AngularJSフロントエンドを実行する組み込みChromiumクライアントです。彼らは単純な魔法の鍵を使って私のAPIで認証します-私の非常に限られた規模で十分です。
現在、APIのデプロイをテストしていますが、AngularクライアントがFlaskサービスにOPTIONS httpメソッドを送信しようとしています。その間、私のAPIは404で応答しています(OPTIONSハンドラーはまだ作成しておらず、PUTハンドラーのみを作成しているため)。 POSTまたはGETではないクロスドメインリクエストを送信する場合、AngularはサーバーでプリフライトOPTIONSメソッドを送信し、クロスドメインリクエストが受け入れられるようにします実際のリクエストを送信する前に。そうですか?
とにかく、Flask Restful APIへのすべてのクロスドメインPUTリクエストを許可するにはどうすればよいですか?以前に(非レストフル)Flaskインスタンスでクロスドマイオンデコレータを使用したことがありますが、APIにOPTIONSハンドラーも記述する必要がありますか?
FlaskバックエンドをPUT応答のAccess-Control-Allow-Originヘッダーで応答するように書き直すことで問題を解決しました。さらに、Flask appは、HTTP RFCで読んだ内容に従ってオプションメソッドに回答します。
PUTメソッドの戻り値は次のようになります。
return restful.request.form, 201, {'Access-Control-Allow-Origin': '*'}
私のOPTIONSメソッドハンドラは次のようになります。
def options (self):
return {'Allow' : 'PUT' }, 200, \
{ 'Access-Control-Allow-Origin': '*', \
'Access-Control-Allow-Methods' : 'PUT,GET' }
@tbicrは正しい:Flask OPTIONSメソッドに自動的に応答します。ただし、私の場合は、その応答でAccess-Control-Allow-Originヘッダーを送信していなかったので、私のブラウザ私は、クロスドメインリクエストが許可されていないことを示唆しているように見えるAPIから応答を受け取っていました。私は、オプションリクエストをオーバーロードし、ACAOヘッダーを追加し、ブラウザはそれで満足しているようで、OPTIONSをフォローアップしましたPUTも機能しました。
Flask-CORS モジュールを使用すると、コードを変更せずにドメイン間リクエストを実行できます。
from flask.ext.cors import CORS
app = Flask(__name__)
cors = CORS(app, resources={r"/api/*": {"origins": "*"}})
Eric が提案したように、flask.ext.cors
モジュールは非推奨になりました。次のコードを使用する必要があります。
from flask_cors import CORS
app = Flask(__name__)
cors = CORS(app, resources={r"/api/*": {"origins": "*"}})
After_requestフックを使用できます:
@ app.after_request def after_request(response): response.headers.add( 'Access-Control-Allow-Origin'、 '*') response.headers.add( 'Access-Control-Allow-Headers'、 'Content-Type、Authorization') response.headers.add( 'Access-Control-Allow-Methods'、 'GET、PUT、 POST、DELETE ') return response
詳細については、このチュートリアルを確認してください- http://tutsbucket.com/tutorials/building-a-blog-using-flask-and-angularjs-part-1/
ブラウザーの実際のリクエストの前に毎回呼び出されるOPTIONS
メソッドです。 OPTIONS
応答では、メソッドとヘッダーが許可されています。 Flask OPTIONS
リクエストを自動的に処理します。
クロスドメインリクエストにアクセスするには、APIにAccess-Control-Allow-Origin
ヘッダーが必要です。特定のドメインを含めることができますが、任意のドメインからのリクエストを許可する場合は、Access-Control-Allow-Origin: *
に設定できます。
flask
にCORSを設定するには、1つの拡張コードを見るか、この拡張機能を使用してみてください: https://github.com/wcdolphin/flask-cors/blob/master/flask_cors.py 。
flask-restful
のCORSを設定するには、このプルリクエストをご覧ください。 https://github.com/twilio/flask-restful/pull/122 および https:// github。 com/twilio/flask-restful/pull/131 。しかし、flask-restful
はデフォルトではまだサポートしていません。
このコメントの更新です。 Flask CORSを使用する方法がありますが、flask.ext.corsは非推奨です。
つかいます: from flask_cors import CORS
この回避策はどうですか:
_from flask import Flask
from flask.ext import restful
from flask.ext.restful import Api
from flask.ext.sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config.from_object('config')
#flask-sqlalchemy
db = SQLAlchemy(app)
#flask-restful
api = restful.Api(app)
@app.after_request
def after_request(response):
response.headers.add('Access-Control-Allow-Origin', '*')
response.headers.add('Access-Control-Allow-Headers', 'Content-Type,Authorization')
response.headers.add('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE')
return response
import views
_
これは this チュートリアルから取りました。とても良い作品です。実際、これはこれまで見てきた中で最高のアプローチだと思います。
各エンドポイントで_{'Access-Control-Allow-Origin': '*'}
_を返すことは、すべてのエンドポイントで追加する必要があるため、効率的ではないようです。少々イライラする...、少なくとも私にとっては。
@cors.crossdomain(Origin='*')
を試しましたが、[〜#〜] get [〜#〜]リクエストでのみ動作するようです。
WebサービスAPIでリモートCORSリクエストを許可するには、次のようにflask restful APIを初期化するだけです。
from flask import Flask
from flask_restful import reqparse, abort, Api, Resource
from flask_cors import CORS
app = Flask(__name__)
cors = CORS(app, resources={r"*": {"origins": "*"}})
api = Api(app)
これにより、APIインスタンスにCORSヘッダーが追加され、すべてのOriginからのすべてのパスでCORSリクエストが許可されます。
装飾を使って解決するのが好きです。
def cross_Origin(origin="*"):
def cross_Origin(func):
@functools.wraps(func)
def _decoration(*args, **kwargs):
ret = func(*args, **kwargs)
_cross_Origin_header = {"Access-Control-Allow-Origin": Origin,
"Access-Control-Allow-Headers":
"Origin, X-Requested-With, Content-Type, Accept"}
if isinstance(ret, Tuple):
if len(ret) == 2 and isinstance(ret[0], dict) and isinstance(ret[1], int):
# this is for handle response like: ```{'status': 1, "data":"ok"}, 200```
return ret[0], ret[1], _cross_Origin_header
Elif isinstance(ret, basestring):
response = make_response(ret)
response.headers["Access-Control-Allow-Origin"] = Origin
response.headers["Access-Control-Allow-Headers"] = "Origin, X-Requested-With, Content-Type, Accept"
return response
Elif isinstance(ret, Response):
ret.headers["Access-Control-Allow-Origin"] = Origin
ret.headers["Access-Control-Allow-Headers"] = "Origin, X-Requested-With, Content-Type, Accept"
return ret
else:
raise ValueError("Cannot handle cross Origin, because the return value is not matched!")
return ret
return _decoration
return cross_Origin
そして、安らかなAPIで装飾を使用します。
class ExampleRestfulApi(Resource)
@cross_Origin()
def get(self):
# allow all cross domain access
pass
@cross_Origin(origin="192.168.1.100")
def post(self):
# allow 192.168.1.100 access
pass