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