Совместное использование ресурсов с помощью PrototypeJS
У меня возникли проблемы с совместным использованием ресурсов и прототипов. У меня есть простой почтовый запрос к зарубежному ресурсу, и для простого почтового запроса есть несколько правил, которые должны быть выполнены:
Content-Type должен быть включен в application/x-www-form-urlencoded, multipart/form-data или text/plain. Простой запрос не устанавливает настраиваемые заголовки с помощью http-запроса, а Сервер должен установить Access- Заголовок Control-Allow-Origin правильный.
с ванильным JavaScript XMLHttpRequest все работает нормально, но с PrototypeJS он не будет работать, потому что он показывает, что Prototype устанавливает несколько пользовательских заголовков, и я не знаю, как это предотвратить.
Я попробовал это в Prototype через:
new Ajax.Request('some.foreign-host.com/res.php', {
method: 'post',
postBody: 'foo=bar',
contentType: 'application/x-www-form-urlencoded',
onSuccess: function(e){
// some custom code
}
});
Есть идеи, как заставить Prototype отправить такой простой запрос CORS?
У меня есть дамп заголовков, созданных простым JavaScript XMLHttpRequest:
POST /bthesis/returnJSON.php HTTP/1.1
Host: foreign-host.com
Connection: keep-alive
Referer: this-host.com
Content-Length: 9
Origin: this-host.com
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Accept: */*
User-Agent: [...]
Accept-Encoding: gzip,deflate,sdch
Accept-Language: de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
и Заголовки, созданные Запросом Прототипа:
OPTIONS /bthesis/returnJSON.php HTTP/1.1
Host: foreign-host.com
Connection: keep-alive
Referer: this-host.com
Access-Control-Request-Method: POST
Origin: this-host.com
Access-Control-Request-Headers: X-Prototype-Version, X-Requested-With, Content-type, Accept
Accept: */*
User-Agent: [...]
Accept-Encoding: gzip,deflate,sdch
Accept-Language: de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
Prototype использует совершенно другой набор заголовков... что приводит к следующей ошибке в консоли:
XMLHttpRequest не может загрузить foreign-host.com/bthesis/returnJSON.php. Поле заголовка запроса X-Prototype-Version не разрешено Access-Control-Allow-Headers. Отказался получить небезопасный заголовок "X-JSON"
Странно то, что веб-сервер в обоих случаях возвращает запрошенный ресурс (я вижу его в представлении "Ресурсы" консоли разработчика в Chrome), но он показывает, что прототип не имеет к нему доступа.
4 ответа
У меня та же проблема. Ссылка @mplungjan поделился содержит ответ:
Вы просто должны сообщить браузеру, что x-json
заголовок безопасен при использовании access-control-expose-headers
Я использую эту строку в контроллере Ruby on Rails
headers['Access-Control-Expose-Headers'] = 'x-json'
(Это должно быть довольно легко перевести на другие языки программирования:))
Подробнее на этой странице
Я нашел решение по другому такому вопросу. И это работает для меня - подробности здесь.
Подводя итог - нужно onCreate
событие в вашем Ajax.Request
который удаляет нестандартные заголовки:
onCreate: function(response) { // here comes the fix
var t = response.transport;
t.setRequestHeader = t.setRequestHeader.wrap(function(original, k, v) {
if (/^(accept|accept-language|content-language)$/i.test(k))
return original(k, v);
if (/^content-type$/i.test(k) &&
/^(application\/x-www-form-urlencoded|multipart\/form-data|text\/plain)(;.+)?$/i.test(v))
return original(k, v);
return;
});
}
Пожалуйста, посмотрите на PREFLIGHT здесь https://developer.mozilla.org/En/HTTP_access_control
Ваша проблема в том, что Fx реагирует на пользовательские заголовки (X-...) и запускает предварительную проверку. Вам потребуется, чтобы сервер возвратил все заголовки контроля доступа для OPTIONS и POST и разрешил настраиваемые заголовки.
Может быть, вы можете установить заголовок источника в Ajax-запросе, например, так
new Ajax.Request('some.foreign-host.com/res.php', {
method: 'post',
postBody: 'foo=bar',
requestHeaders: {Origin: 'http://www.my.local-host.com'}
contentType: 'application/x-www-form-urlencoded',
onSuccess: function(e){
// some custom code
}
});
Хотя сам никогда не пробовал... Что происходит с версией Prototype? Выполняется ли запрос, а затем ничего не возвращается, или ответ отклоняется, или как?