Bottle Py: jQuery AJAX 요청에 대한 CORS 활성화
Bottle Web Framework에서 웹 서비스의 RESTful API를 작업하고 있으며 jQuery AJAX 호출로 리소스에 액세스하고 싶습니다.
REST 클라이언트를 사용하면 리소스 인터페이스가 의도한 대로 작동하고 GET, POST, ... 요청을 적절하게 처리합니다.그러나 jQuery AJAX POST 요청을 보낼 때 결과 OPTIONS 사전 비행 요청은 '405: Method not allowed'로 거부됩니다.
http://bottlepy.org/docs/dev/recipes.html#using-the-hooks-plugin 에서 설명한 것처럼 Bottle 서버에서 CORS를 활성화하려고 했지만 OPTIONS 요청에 대해 after_request 후크가 호출되지 않습니다.
다음은 제 서버의 발췌본입니다.
from bottle import Bottle, run, request, response
import simplejson as json
app = Bottle()
@app.hook('after_request')
def enable_cors():
print "after_request hook"
response.headers['Access-Control-Allow-Origin'] = '*'
response.headers['Access-Control-Allow-Methods'] = 'GET, POST, PUT, OPTIONS'
response.headers['Access-Control-Allow-Headers'] = 'Origin, Accept, Content-Type, X-Requested-With, X-CSRF-Token'
@app.post('/cors')
def lvambience():
response.headers['Content-Type'] = 'application/json'
return "[1]"
[...]
jQuery AJAX 통화:
$.ajax({
type: "POST",
url: "http://192.168.169.9:8080/cors",
data: JSON.stringify( data ),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(data){
alert(data);
},
failure: function(err) {
alert(err);
}
});
서버는 405 오류만 기록합니다.
192.168.169.3 - - [23/Jun/2013 17:10:53] "OPTIONS /cors HTTP/1.1" 405 741
$.post는 작동하지만 PUT 요청을 전송할 수 없으면 RESTful 서비스의 목적을 달성할 수 없습니다.OPTIONS 사전 비행 요청이 처리되도록 하려면 어떻게 해야 합니까?
후크 대신 핸들러를 설치합니다.
제가 과거에 이것을 보완하는 두 가지 방법이 있습니다: 데코레이터 또는 보틀 플러그인.둘 다 보여드릴 테니 둘 중 하나(또는 둘 다)가 귀하의 요구에 적합한지 결정하시면 됩니다.두 경우 모두 일반적인 개념은 핸들러가 응답을 클라이언트로 다시 전송하기 전에 가로채서 CORS 헤더를 삽입한 다음 응답을 반환하는 것입니다.
방법 1: 경로별 설치(데코레이터)
이 방법은 일부 경로에서만 처리기를 실행하려는 경우에 적합합니다.실행할 각 경로를 장식하기만 하면 됩니다.다음은 예입니다.
import bottle
from bottle import response
# the decorator
def enable_cors(fn):
def _enable_cors(*args, **kwargs):
# set CORS headers
response.headers['Access-Control-Allow-Origin'] = '*'
response.headers['Access-Control-Allow-Methods'] = 'GET, POST, PUT, OPTIONS'
response.headers['Access-Control-Allow-Headers'] = 'Origin, Accept, Content-Type, X-Requested-With, X-CSRF-Token'
if bottle.request.method != 'OPTIONS':
# actual request; reply with the actual response
return fn(*args, **kwargs)
return _enable_cors
app = bottle.app()
@app.route('/cors', method=['OPTIONS', 'GET'])
@enable_cors
def lvambience():
response.headers['Content-type'] = 'application/json'
return '[1]'
app.run(port=8001)
방법 2: 전체적으로 설치(보틀 플러그인)
이 방법은 처리기가 모든 경로 또는 대부분의 경로에서 실행되도록 하려는 경우 선호됩니다.한 번만 Bottle 플러그인을 정의하면 Bottle이 모든 경로에서 자동으로 이 플러그인을 호출합니다. 각 경로에 데코레이터를 지정할 필요가 없습니다. (경로의 플러그인을 사용할 수 있습니다.)skip경로별로 이 핸들러를 방지하는 매개 변수입니다.)다음은 위의 예에 해당하는 예입니다.
import bottle
from bottle import response
class EnableCors(object):
name = 'enable_cors'
api = 2
def apply(self, fn, context):
def _enable_cors(*args, **kwargs):
# set CORS headers
response.headers['Access-Control-Allow-Origin'] = '*'
response.headers['Access-Control-Allow-Methods'] = 'GET, POST, PUT, OPTIONS'
response.headers['Access-Control-Allow-Headers'] = 'Origin, Accept, Content-Type, X-Requested-With, X-CSRF-Token'
if bottle.request.method != 'OPTIONS':
# actual request; reply with the actual response
return fn(*args, **kwargs)
return _enable_cors
app = bottle.app()
@app.route('/cors', method=['OPTIONS', 'GET'])
def lvambience():
response.headers['Content-type'] = 'application/json'
return '[1]'
app.install(EnableCors())
app.run(port=8001)
다음은 CORS 핸들러를 전체적으로 설치하기 위한 on @ron.ro thman의 방법 #2의 사소한 개선 사항입니다.그의 방법은 당신이 그것을 지정하도록 요구합니다.OPTIONS메서드는 선언하는 모든 경로에서 허용됩니다.이 솔루션은 모두에 대한 글로벌 처리기를 설치합니다.OPTIONS요청한다.
@bottle.route('/<:re:.*>', method='OPTIONS')
def enable_cors_generic_route():
"""
This route takes priority over all others. So any request with an OPTIONS
method will be handled by this function.
See: https://github.com/bottlepy/bottle/issues/402
NOTE: This means we won't 404 any invalid path that is an OPTIONS request.
"""
add_cors_headers()
@bottle.hook('after_request')
def enable_cors_after_request_hook():
"""
This executes after every route. We use it to attach CORS headers when
applicable.
"""
add_cors_headers()
def add_cors_headers():
if SOME_CONDITION: # You don't have to gate this
bottle.response.headers['Access-Control-Allow-Origin'] = '*'
bottle.response.headers['Access-Control-Allow-Methods'] = \
'GET, POST, PUT, OPTIONS'
bottle.response.headers['Access-Control-Allow-Headers'] = \
'Origin, Accept, Content-Type, X-Requested-With, X-CSRF-Token'
```
그리고 당신은 실제로 이것을 사용해야 하지 않나요?
response.set_header('Access-Control-Allow-Origin', '*')
response.add_header('Access-Control-Allow-Methods', 'GET, POST, PUT, OPTIONS')
Bottle이 아닌 웹 서버가 헤더를 설정하도록 합니다.
이것이 당신의 상황에 적용되는지는 확실하지 않지만, 나는 아파치에서 내 보틀 애플리케이션의 CORS 헤더를 설정함으로써 과거 프로젝트의 문제를 해결했습니다.구성이 간편하고, Python 코드를 깔끔하고 깨끗하게 유지하며, 효율적입니다.
다양한 소스에서 정보를 얻을 수 있지만 Apache를 사용하는 경우에는 다음과 같이 구성됩니다.
<Location "/cors">
Header set Access-Control-Allow-Headers "Origin, Content-Type"
Header set Access-Control-Allow-Methods "POST, GET, OPTIONS"
Header set Access-Control-Allow-Origin "*"
Header set Access-Control-Request-Headers "Origin, Content-Type"
</Location>
언급URL : https://stackoverflow.com/questions/17262170/bottle-py-enabling-cors-for-jquery-ajax-requests
'codememo' 카테고리의 다른 글
| 장식된 기능의 서명 보존 (0) | 2023.08.01 |
|---|---|
| free()는 메모리를 제로로 만드는 것입니까? (0) | 2023.08.01 |
| 보기에 ID를 프로그래밍 방식으로 할당하려면 어떻게 해야 합니까? (0) | 2023.08.01 |
| Swift를 사용하여 iOS에서 SMS 보내기 (0) | 2023.08.01 |
| PHP Ajax 업로드 진행률 표시줄 (0) | 2023.07.27 |