Предварительное поле CORS возвращается с Access-Control-Allow-Origin: *, браузер все еще не выполняет запрос
Запуск AJAX GET
до http://qualifiedlocalhost:8888/resource.json
запускает ожидаемый предварительный полет CORS, который выглядит так, как будто он возвращается правильно:
Запрос перед полетом OPTIONS
Request URL:http://qualifiedlocalhost:8888/resource.json
Request Method:OPTIONS
Status Code:200 OK
Заголовок запроса
Accept:*/*
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Access-Control-Request-Headers:accept, origin, x-requested-with
Access-Control-Request-Method:GET
Cache-Control:no-cache
Connection:keep-alive
Host:qualifiedlocalhost:8888
Origin:http://localhost:9000
Pragma:no-cache
Referer:http://localhost:9000/
User-Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.71 Safari/537.36
Заголовки ответов
Access-Control-Allow-Headers:Content-Type, X-Requested-With
Access-Control-Allow-Methods:GET,PUT,POST,DELETE
Access-Control-Allow-Origin:*
Connection:keep-alive
Content-Length:2
Content-Type:text/plain
Date:Thu, 01 Aug 2013 19:57:43 GMT
Set-Cookie:connect.sid=s%3AEpPytDm3Dk3H9V4J9y6_y-Nq.Rs572s475TpGhCP%2FK%2B2maKV6zYD%2FUg425zPDKHwoQ6s; Path=/; HttpOnly
X-Powered-By:Express
Хорошо выглядеть?
Итак, он должен работать, правильно?
Но последующий запрос все еще не выполняется с ошибкой XMLHttpRequest cannot load http://qualifiedlocalhost:8888/resource.json. Origin http://localhost:9000 is not allowed by Access-Control-Allow-Origin.
Истинный запрос
Request URL:http://qualifiedlocalhost:8888/resource.json
Заголовок запроса
Accept:application/json, text/plain, */*
Cache-Control:no-cache
Origin:http://localhost:9000
Pragma:no-cache
Referer:http://localhost:9000/
User-Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.71 Safari/537.36
X-Requested-With:XMLHttpRequest
Помогите!
Может быть, он смотрит прямо передо мной. Но какие-нибудь идеи? На всякий случай это актуально... Я использую AngularJS $resource
и разговариваю с CompoundJS-сервером.
Ответы
Ответ 1
измените свои методы управления доступом-Allow: "GET, POST" для "GET, POST, PUT, DELETE"
перед:
app.use(function(req, res, next) {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST');
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type, Authorization');
next();
});
После:
app.use(function(req, res, next) {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT ,DELETE');
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type, Authorization');
next();
});
Ответ 2
Является ли ваш веб-сервер/функция get ТАКЖЕ, включая HTTP-заголовок: Access-Control-Allow-Origin? В итоге я нашел успех с этим дополнением, используя AngularJS 1.0.7 и удаленный Java-сервлет. Вот мой фрагмент кода Java - никаких изменений в клиенте AngularJS не было:
Servlet:
@Override
protected void doOptions(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// Send Response
super.doOptions(request, response);
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Headers", "Content-Type, X-Requested-With");
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
/* ... */
response.setHeader("Access-Control-Allow-Origin", "*");
}
Более элегантной альтернативой является фильтр сервлетов.
Ответ 3
I недавно была та же проблема. Проблема в том, что заголовок Access-Control-Allow-Origin
(и, если вы используете его, заголовок Access-Control-Allow-Credentials
) должен быть отправлен в и ответ перед полетом и фактический ответ.
В вашем примере это будет только в предполетном ответе.
Ответ 4
Мы заметили ту же проблему, когда сервер отправляет правильные заголовки CORS, но браузер терпит неудачу, поскольку он считает, что требования CORS не выполняются. Что более интересно, в нашем случае это происходит только на некоторых вызовах AJAX в том же сеансе браузера, но не на всех.
Теория работы...
Очистка кеша браузера решает проблему в нашем случае. Моя нынешняя рабочая теория заключается в том, что это связано с тем, что файлы cookie устанавливаются сервером кросс-исходного кода. Я заметил, что в вашем сценарии есть файл cookie, который устанавливается как часть ответа на запрос перед полетом OPTIONS. Вы пытались заставить сервер не устанавливать файлы cookie для запросов, поступающих из другого источника?
Однако мы заметили, что в некоторых случаях проблема повторилась после сброса браузера. Кроме того, запуск браузера в приватном режиме приводит к тому, что проблема исчезает, указывая на некоторую проблему, связанную с тем, что в кеше браузера.
Для справки, вот мой сценарий (я почти разместил это как новый вопрос в SO, но вместо этого поставил его здесь):
Мы столкнулись с ошибкой, когда некоторые запросы CORS GET, выполненные с помощью jQuery.ajax, терпели неудачу. В данном сеансе браузера мы видим запрос перед полетом OPTIONS, за которым следует фактический запрос. На той же сессии некоторые запросы проходят, а другие терпят неудачу.
Последовательность запросов и ответов в сетевой консоли браузера выглядит следующим образом:
Сначала предварительный запрос OPTIONS
OPTIONS /api/v1/users/337/statuses
HTTP/1.1 Host: api.obfuscatedserver.com
Connection: keep-alive
Access-Control-Request-Method: GET
Origin: http://10.10.8.84:3003
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.95 Safari/537.36
Access-Control-Request-Headers: accept, origin, x-csrf-token, auth
Accept: */* Referer: http://10.10.8.84:3003/
Accept-Encoding: gzip,deflate,sdch Accept-Language: en-US,en;q=0.8
Что получает ответ вроде:
HTTP/1.1 200 OK
Date: Tue, 06 Aug 2013 19:18:22 GMT
Server: Apache/2.2.22 (Ubuntu)
Access-Control-Allow-Origin: http://10.10.8.84:3003
Access-Control-Allow-Methods: GET, POST, OPTIONS, PUT
Access-Control-Max-Age: 1728000
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: accept, origin, x-csrf-token, auth
X-UA-Compatible: IE=Edge,chrome=1
Cache-Control: no-cache
X-Request-Id: 4429c4ea9ce12b6dcf364ac7f159c13c
X-Runtime: 0.001344
X-Rack-Cache: invalidate, pass
X-Powered-By: Phusion
Passenger 4.0.2
Status: 200 OK
Vary: Accept-Encoding
Content-Encoding: gzip
Затем фактический запрос GET,
GET https://api.obfuscatedserver.com/api/v1/users/337
HTTP/1.1
Accept: application/json, text/javascript, */*; q=0.01
Referer: http://10.10.8.84:3003/
Origin: http://10.10.8.84:3003
X-CSRF-Token: xxxxxxx
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.95 Safari/537.36
auth: xxxxxxxxx
Что вызывает ошибку в консоли браузера, например,
XMLHttpRequest
cannot load https://api.obfuscatedserver.com/api/v1/users/337.
Origin http://10.10.8.84:3003 is not allowed by Access-Control-Allow-Origin.
Дополнительная отладка
Я могу воспроизвести одну и ту же последовательность с помощью curl, и я вижу действительные ответы, поступающие с сервера. то есть у них есть ожидаемые заголовки CORS, которые должны пропускать запросы.
Выполнение того же сценария в окне браузера in-private/incognito не воспроизводило проблему. Это заставило меня попробовать очистить кеш, и это заставило проблему уйти. Но через некоторое время он вернулся.
Проблема воспроизводилась на iPhone Safari, а также на Chrome на рабочем столе OSX.
Что мне действительно нужно с помощью
Я подозреваю, что в домене кросс-происхождения есть несколько файлов cookie, которые здесь участвуют и потенциально могут выявить ошибку в браузере. Есть ли инструменты или точки останова, которые я могу установить в браузере (собственный стек?), Чтобы попробовать и отладить это дальше? Точка останова в коде, которая оценивает политику CORS, была бы идеальной.
Ответ 5
Похоже, ваш ответ на "параметры" работает нормально. Проблема, кажется, в ответе "получить" .
Вы хотите, чтобы ваш ответ "получить" возвращал те же заголовки CORS, что и ответ "options".
В частности, ответ "получить" должен включать
Access-Control-Allow-Headers:Content-Type, X-Requested-With
Access-Control-Allow-Methods:GET,PUT,POST,DELETE
Access-Control-Allow-Origin:*
Ответ 6
используйте модуль cors, чтобы избежать проблемы
var cors = require('cors')
var app = express()
app.use(cors())