Подтвердить что ты не робот

Неверный запрос AJAX

Я вызываю POST на стороннем API, с которым я работал с помощью функции jQuery $.ajax. Однако, когда я делаю вызов, я получаю следующую ошибку: XMLHttpRequest cannot load http://the-url.com. The request was redirected to 'http://the-url.com/anotherlocation', which is disallowed for cross-origin requests that require preflight.

Я видел из этого сообщения, что это может быть ошибка Webkit, поэтому я попробовал ее в Firefox (я развиваюсь в Chrome), и я получил тот же результат. Я пробовал это в Chrome и Firefox, и получаю тот же результат.

Per этот пост, я также попытался использовать jsonp, установив свойство crossDomain функции $.ajax на true и установив dataType до jsonp. Но это вызвало ошибку внутреннего сервера 500.

Когда я запускаю Chrome с флагом --disable-web-security, у меня нет никаких проблем. Однако, если я запускаю браузер в обычном режиме, я получаю сообщение об ошибке.

Итак, я думаю, это может быть вопрос из двух частей. Что я могу сделать для этого междоменного запроса? Если JSONP является ответом, то как мне узнать, правильно ли настроен сторонний API для поддержки этого?

EDIT: снимок экрана, когда я делаю вызов с отключенной защитой браузера: https://drive.google.com/file/d/0Bzo7loNBQcmjUjk5YWNWLXM2SVE/edit?usp=sharing

Здесь экранная проверка, когда я делаю вызов с включенной защитой браузера (например, обычный): https://drive.google.com/file/d/0Bzo7loNBQcmjam5NQ3BKWUluRE0/edit?usp=sharing

4b9b3361

Ответ 1

Решением, которое я придумал, было использование cURL (как упоминалось в @waki), но немного модифицированная версия, которая поддерживает SOAP. Затем вместо вызова AJAX стороннему API (который настроен неправильно) я вызываю свой локальный PHP файл, который затем выдает SOAP-вызов стороннему API и передает данные обратно в мой PHP файл, где я могу затем обработайте его. Это позволяет мне забыть о CORS и всех связанных с этим сложностях. Здесь код (взятый и измененный из этого вопроса, но без аутентификации).

$post_data = "Some xml here";
$soapUrl = "http://yoursite.com/soap.asmx"; // asmx URL of WSDL


$headers = array(
    "Content-type: text/xml;charset=\"utf-8\"",
    "Accept: text/xml",
    "Cache-Control: no-cache",
    "Pragma: no-cache",
    "SOAPAction: http://yoursite.com/SOAPAction",
    "Content-length: " . strlen($post_data),
); //SOAPAction: your op URL

$url = $soapUrl;

// PHP cURL
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data); // the SOAP request
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$response = curl_exec($ch);

/* Check for an error when processing the request. */
if(curl_errno($ch) != 0) {
   // TODO handle the error
}

curl_close($ch);

// TODO Parse and process the $response variable (returned as XML)

Ответ 2

К вашему первому вопросу,

Что я могу сделать, чтобы сделать этот кросс-доменный запрос?

Следующие заголовки запросов сначала отправляются на сервер. На основе заголовков ответов пользователь UserAgent, то есть браузер здесь, отбросит ответ (если он есть) и не вернет его обратно в обратный вызов XHR, когда заголовки не будут добавлены.

Origin: http://yourdomain.com Access-Control-Request-Method: POST Access-Control-Request-Headers: X-Custom-Header

Затем ваш сервер должен ответить на следующие заголовки:

Access-Control-Allow-Origin: http://yourdomain.com Access-Control-Allow-Methods: GET, POST, OPTIONS Access-Control-Allow-Headers: X-Custom-Header

Пример взято из - fooobar.com/questions/9351/...

Вы можете использовать такие инструменты, как вкладка "Фиддлер" или вкладка "Сеть веб-инспекторов" (Chrome) или "Firebug", чтобы найти заголовки, которые сервер отправляет обратно в ответ на ваш запрос.

URL-адрес стороннего API-сервера должен отвечать на поддерживаемые значения. Если это не так, ваша проблема.

Невозможно помочь в ошибке сервера JsonP 500, так как он говорит Внутренняя ошибка сервера


UPDATE

Я видел ваши снимки экрана, пару вещей, чтобы заметить здесь.

  • HTTP POST используется
  • Нет Access-Control заголовки, найденные в обоих режимах. Со вторым кодом состояния 302
  • Origin заголовок запроса null, поэтому я считаю, что файл HTML открывается из файловой системы, а не с веб-сайта

Включение JSONP

В соответствии с тем, почему JSONP не работает, причина. Конфигурация веб-службы (указанного ASMX) не включила режим GET для запроса. JSONP не работает с POST.

Почему 200 с отключенной безопасностью?

Запрос POST напрямую вызывается без запроса OPTIONS или предварительного запроса, перед которым он запускается, поэтому сервер просто отвечает.

Почему 302 код состояния с включенной безопасностью?

Сначала немного о том, как это происходит, когда флаг безопасности не отключен (по умолчанию). Запрос OPTIONS запускается по URL-адресу. URL-адрес должен ответить назад на список методов HTTP, которые можно использовать, т.е. GET, POST и т.д. Код состояния этого запроса OPTIONS должен быть 200.

В текущем случае при выполнении этого происходит перенаправление. И перенаправление указывает на собственный обработчик ошибок для HTTP-сервера. Я считаю, что ошибка 404, которая улавливается и перенаправляется. [Это может быть из-за того, что пользовательский обработчик установлен в ResponseRedirect вместо ResponseRewrite]. Причина для 404 - это междоменный доступ не включен.

Если пользовательская обработка ошибок была отключена, это вернуло бы код HTTP 500. Я считаю, что проблему можно найти, проверив журналы сервера сразу же после запуска междоменного запроса. Будет полезно проверить журналы сервера на наличие ошибок, кроме этого, если они есть.

Возможное решение

Чтобы разрешить доступ, существует два пути: подробнее здесь. Или напрямую добавьте заголовки контроля доступа в раздел web.config file customheaders.

Если междоменный доступ включен, сервер должен ответить на ОПЦИИ и разрешить прохождение запроса. Это должно возвращать HTTP 200, если нет других ошибок. Но обратный вызов ajax не сможет получить доступ к ответу. Это можно сделать только в том случае, если для параметра Access-Control-Allow-Origin установлено значение "*" или Origin значение заголовка запроса и Access-Control по мере необходимости. И обратный вызов ajax получит ответ, как предполагалось.

Третья точка, null Origin. Это будет проблемой, если значение заголовка запроса Origin будет отправлено обратно как Access-Control-Allow-Origin. Но я предполагаю, что вы перемещаете свою HTML-страницу на веб-сервер, поэтому это не должно быть проблемой.

Надеюсь, это поможет!

Ответ 3

Вы можете использовать cURL? С помощью Ajax вы отправляете данные своему обработчику (на вашем сервере, позвольте callback.php). В вашем файле (callback.php) используйте cURL с вашими данными:

$post_data = array( 
    'key' => 'key', 
    'test' => 'text'
    ); 

$curl = curl_init(); 
curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE); 
curl_setopt($curl, CURLOPT_POST, TRUE); 
curl_setopt($curl, CURLOPT_POSTFIELDS, $post_data);  
curl_setopt($curl, CURLOPT_URL, 'http://www.domain.com/'); 
$return = json_decode(trim(curl_exec($curl)), TRUE); 
curl_close($curl); 

в переменной $return вы получите свои данные.