Запрос между источниками заблокирован

Итак, у меня есть обработчик Go http, который сохраняет некоторое содержимое POST в хранилище данных и извлекает в ответ некоторую другую информацию. На заднем плане я использую:

func handleMessageQueue(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Access-Control-Allow-Origin", "*")
    if r.Method == "POST" {

        c := appengine.NewContext(r)

        body, _ := ioutil.ReadAll(r.Body)

        auth := string(body[:])
        r.Body.Close()
        q := datastore.NewQuery("Message").Order("-Date")

        var msg []Message
        key, err := q.GetAll(c, &msg)

        if err != nil {
            c.Errorf("fetching msg: %v", err)
            return
        }

        w.Header().Set("Content-Type", "application/json")
        jsonMsg, err := json.Marshal(msg)
        msgstr := string(jsonMsg)
        fmt.Fprint(w, msgstr)
        return
    }
}

В моем приложении Firefox OS я использую:

var message = "content";

request = new XMLHttpRequest();
request.open('POST', 'http://localhost:8080/msgs', true);

request.onload = function () {
    if (request.status >= 200 && request.status < 400) {
        // Success!
        data = JSON.parse(request.responseText);
        console.log(data);
    } else {
        // We reached our target server, but it returned an error
        console.log("server error");
    }
};

request.onerror = function () {
    // There was a connection error of some sort
    console.log("connection error");
};

request.send(message);

Входящая часть все работает и все такое. Однако мой ответ блокируется. Давая мне следующее сообщение:

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:8080/msgs. This can be fixed by moving the resource to the same domain or enabling CORS.

Я пробовал много других вещей, но я не могу просто получить ответ от сервера. Однако, когда я меняю свой метод Go POST на GET и получаю доступ к странице через браузер, я получаю данные, которые мне так нужны. Я не могу решить, какая сторона пошла не так и почему: может быть, Go не должен блокировать такие запросы, но также может быть и то, что мой javascript незаконен.


person Dani    schedule 12.03.2014    source источник
comment
Мне кажется (я не пишу это как ответ, так как не уверен), что вы не устанавливаете тип контента в запросе. Из TFM от Mozilla на эту тему: If POST is used to send data to the server, the Content-Type of the data sent to the server with the HTTP POST request is one of application/x-www-form-urlencoded, multipart/form-data, or text/plain   -  person Not_a_Golfer    schedule 13.03.2014


Ответы (3)


@Egidius, при создании XMLHttpRequest вы должны использовать

var xhr = new XMLHttpRequest({mozSystem: true});

Что такое mozSystem?

mozSystem Boolean: установка для этого флага значения true позволяет устанавливать соединения между сайтами, не требуя согласия сервера с помощью CORS. Требуется настройка mozAnon: true, т. е. это нельзя сочетать с отправкой файлов cookie или других учетных данных пользователя. Это работает только в привилегированных (проверенных) приложениях; он не работает на произвольных веб-страницах, загруженных в Firefox.

Изменения в вашем манифесте

В своем манифесте не забудьте включить эту строку в свои разрешения:

"permissions": {
       "systemXHR" : {},
}
person msaad    schedule 13.03.2014
comment
типичный; Я должен был rtfm лучше. Раньше я пробовал использовать аргумент mozSystem xhr, но пропустил часть манифеста, потому что это недействительный JSON. Теперь я только что добавил немного ерунды, и моя ошибка исчезла. Несмотря на то, что я до сих пор не получу ответа, я думаю, что это исправило это, должно быть, это некоторые из моих изменений в попытке исправить ошибку CORS, которая прямо сейчас испортила эту часть. Большое спасибо! - person Dani; 14.03.2014
comment
Добро пожаловать, Эгидий. Cors иногда может быть ерундой, но хорошо, что по умолчанию он считается ложным, потому что многие разработчики не понимают рисков, связанных с таким разрешением. Я рад, что смог помочь. - person msaad; 15.03.2014
comment
Спасибо за эту информацию, но есть ли у вас какие-либо источники? Дополнительная информация? Это не работает для меня. . . - person R Claven; 10.10.2014
comment
@RClaven, конечно. Этот developer.mozilla.org/en-US/docs/Web/API /XMLHttpRequest может вам помочь. Кроме того, убедитесь, что вы не сталкиваетесь с проблемами CORS, а не с разрешениями. - person msaad; 10.10.2014

Вам нужны другие заголовки, а не только access-control-allow-origin. Если в вашем запросе есть заголовок «Access-Control-Allow-Origin», вы должны скопировать его в заголовки ответа. Если нет, вы должны проверить заголовок «Origin» и скопировать его в ответ. Если в вашем запросе нет заголовков Access-Control-Allow-Origin, а не Origin, вы должны вернуть «*».

Вы можете прочитать полное объяснение здесь: http://www.html5rocks.com/en/tutorials/cors/#toc-adding-cors-support-to-the-server

и это функция, которую я использую для написания междоменных заголовков:

func writeCrossDomainHeaders(w http.ResponseWriter, req *http.Request) {
    // Cross domain headers
    if acrh, ok := req.Header["Access-Control-Request-Headers"]; ok {
        w.Header().Set("Access-Control-Allow-Headers", acrh[0])
    }
    w.Header().Set("Access-Control-Allow-Credentials", "True")
    if acao, ok := req.Header["Access-Control-Allow-Origin"]; ok {
        w.Header().Set("Access-Control-Allow-Origin", acao[0])
    } else {
        if _, oko := req.Header["Origin"]; oko {
            w.Header().Set("Access-Control-Allow-Origin", req.Header["Origin"][0])
        } else {
            w.Header().Set("Access-Control-Allow-Origin", "*")
        }
    }
    w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE")
    w.Header().Set("Connection", "Close")

}
person Karl    schedule 13.03.2014
comment
Насколько я хотел бы подтвердить ваш ответ; Я просто не могу заставить его работать. Есть ли способ увидеть, какие заголовки отправляет мой javascript Firefox OS? если я console.log(запрос), я получаю: [объект DeadObject]. Сторона Golang печатает следующий w.Header(): map[Access-Control-Allow-Credentials:[True] Access-Control-Allow-Origin:[app://d8c37181-3d41-5c40-8a1e-3abfa8cb3955] Access- Control-Allow-Methods: [GET, POST]] - person Dani; 14.03.2014
comment
Я использую фаербаг. Это позволяет вам видеть все заголовки и тело запроса и ответа. Теперь, почему в Origin написано: app://? - person Karl; 17.03.2014
comment
Еще одна вещь. Вы отвечаете на метод OPTIONS в своем бэкэнде? Все междоменные запросы сначала вызывают серверную часть с помощью метода OPTION, и если этот метод отвечает заголовками, которые я отправил в своем предыдущем ответе, то выполняется настоящий запрос. Например: если вы выполняете междоменный POST, ваш браузер выполнит запрос OPTIONS к серверной части, и если ответ правильный (серверная часть отвечает на правильные заголовки cors), тогда будет выполнен настоящий POST. - person Karl; 17.03.2014
comment
Я использую Gorilla/Mux, и вот как я обрабатываю запросы OPTIONS: r := mux.NewRouter() r.StrictSlash(true) r.PathPrefix(/).Methods(OPTIONS).HandlerFunc(writeCrossDomainHeaders) r.Handle (/widget, context.Handler(blah_blah_blah)).Методы(GET) - person Karl; 18.03.2014
comment
Привет, Карл, ах, Firebug; Я должен был знать. В источнике написано app://, потому что это приложение ОС Firefox, которое я запускаю. Похоже, что именно эта деталь была причиной моей проблемы, как указано выше @msaad. Я пару раз сталкивался с Gorilla в поисках ответов на Golang, но в тот момент я не понимал, почему я должен его использовать. Но я думаю, мне следует еще раз взглянуть; ваш способ обработки запроса OPTIONS кажется более удобным - person Dani; 18.03.2014

Вы должны поместить этот код в application.rb

config.action_dispatch.default_headers = {
        'Access-Control-Allow-Origin' => '*',
        'Access-Control-Request-Method' => %w{GET POST OPTIONS}.join(",")
}
person sivamani    schedule 29.05.2019