CORS-использование AJAX для публикации на веб-службе Python (webapp2)
это будет долго:
хорошо, поэтому я разрабатываю гаджет календаря google, который отправляет запросы в api REST Python webapp2, размещенный в Google App Engine.
проблема возникает, когда я пытаюсь опубликовать что-то, что он не позволяет мне из-за CORS. В Хромы' инструменты разработчика написано:
Method: OPTIONS.
Status: (failed) Request header field Content-Type is not allowed by Access-Control-Allow-Headers.
Origin https://hq34i4geprnp5vci191ljfuhcoerscl4-a-calendar-opensocial.googleusercontent.com is not allowed by Access-Control-Allow-Origin.
Я знаю, что это из-за CORS. Здесь:
Ajax - ' Origin localhost не допускается Access-Control-Allow-Origin'
Он говорит, что я должен добавить
Access-Control-Allow-Origin: *
к заголовкам, но опять же я новичок в ajax, и мне интересно, сделано ли это так:
$.ajax({
type: "POST",
url: "https://myapp.appspot.com/service",
contentType: "application/json; charset=utf-8",
data: data,
beforeSend: function (request)
{
request.setRequestHeader("Access-Control-Allow-Origin", "*");
}
success: function(data) {
alert("AJAX done");
}
});
добавление этих заголовков вывод разные (что заставляет меня задуматься, было ли разрешено происхождение, хотя я действительно не знаю):
Method: OPTIONS.
Status: (failed) Request header field Content-Type is not allowed by Access-Control-Allow-Headers.
XMLHttpRequest cannot load https://myapp.appspot.com/service. Request header field Access-Control-Allow-Origin is not allowed by Access-Control-Allow-Headers.
Я даже нашел это:
http://james.padolsey.com/javascript/cross-domain-requests-with-jquery/
что позволяет мне получать запросы, но я хотел бы научиться делать их без этого.
также на моем сервере у меня есть это:
...
class webService(webapp2.RequestHandler):
options(self):
self.response.write('options')
post(self):
self.response.write('post')
application = webapp2.WSGIApplication([
('/', MainPage),
('/service', webService)
], debug=True)
Я не знаю, должен ли я добавить что-то еще на веб-сервер, и я не нашел информации, говорящей, что я должен. Также я думаю, что я близок к достижению запроса CORS, но я не могу найти пример, который объясняет это все.
пожалуйста, помогите.
3 ответов
Ок, я исправил это.
прежде всего, я понял здесь что заголовки были отправлены сервером, поэтому я делал неправильно при отправке этих заголовков в запросе AJAX.
наконец, после поиска по всему миру в Интернете я нашел то, что мне не хватало. Это было что-то глупое. Я нашел страницу, которая все исправила:
http://enable-cors.org/server_appengine.html
Итак, наконец, все выглядит так это:
$.ajax({
type: "POST",
url: "https://myapp.appspot.com/service",
contentType: "application/json; charset=utf-8",
data: data,
success: function(data) {
alert("AJAX done");
}
});
и в веб-сервисе:
class webService(webapp2.RequestHandler):
def get(self):
self.response.headers.add_header('Access-Control-Allow-Origin', '*')
self.response.headers['Content-Type'] = 'application/json'
# do something
def post(self):
self.response.headers.add_header('Access-Control-Allow-Origin', '*')
self.response.headers['Content-Type'] = 'application/json'
# do something
def options(self):
self.response.headers['Access-Control-Allow-Origin'] = '*'
self.response.headers['Access-Control-Allow-Headers'] = 'Origin, X-Requested-With, Content-Type, Accept'
self.response.headers['Access-Control-Allow-Methods'] = 'POST, GET, PUT, DELETE'
Я просто хочу указать на деталь, которая может помочь другим:
браузеры отличаются тем, как они обрабатывают заголовок "Access-Control-Allow-Orgin". Например, я обнаружил, что Chrome блокирует междоменные сообщения, когда значение заголовка является подстановочным знаком ( * ), как в коде решения выше. Она считает его слишком либеральным и хочет определенного происхождения. Тем не менее, другие браузеры, такие как IE и FireFox, не заботились.
поэтому, если вы хотите создать кросс-браузерное решение, лучше всего установить значение "Access-Control-Allow-Origin" к исходному значению, отправленному с запросом.
Если вы используете SSL, то вы столкнетесь с некоторыми другими различиями, которые также необходимо будет протестировать.
и если вам нужно легкое решение, все это можно сделать с помощью POJS (plain-old-JavaScript), не прибегая к jQuery. Просто закрой окно.XDomainRequest для IE8+ и окна.XMLHttpRequest для других браузеров, и вы находитесь в бизнесе.
может проще с отправка метод
class BaseRequestHandler(webapp2.RequestHandler):
def dispatch(self):
self.response.headers.add_header('Access-Control-Allow-Origin', '*')
self.response.headers.add_header('Access-Control-Allow-Headers', 'Content-Type')
webapp2.RequestHandler.dispatch(self)
class LoginHandler(BaseRequestHandler):
def login(self):
#code here