JQuery AJAX SOAP, основанные на веб-сервисах и CORS (совместное использование ресурсов)

В течение нескольких недель я пытаюсь получить один из моих межсетевых веб-сервисов на основе jQuery AJAX SOAP для работы с плагином jQuery, который я написал для одного из моих клиентов. Большинство исследований, которые я делал, как представляется, указывали на то, что это было невозможно, потому что CORS или Cross Origin Resource Sharing разрешали только вызовы типа jasonP (GET).

Я, наконец, подумал, как заставить его работать и подумал, что я поделюсь тем, что должен был сделать.

Первое, что нужно понять, это то, что в браузере, поддерживающем CORS, где сервер находится в другом домене, что-либо другое, что GET (среди других параметров) приведет к так называемой проверке перед полетом. Это означает, что браузер запросит у сервера список параметров, которые ему разрешено выполнять. Если сервер не вернет точный список параметров, позволяющих веб-службе на основе SOAP, вызов завершится неудачно даже до того, как будет выполнен фактический запрос.

Что вам нужно сделать, так это сделать веб-сервер (в моем примере он IIS7.5) вернет правильный список параметров.
Вы делаете это, настраивая файл web.config в папке inetpub\wwwroot (если у вас его нет, просто создайте его и скопируйте в него).

Мой файл web.config выглядит так.

Важно, чтобы все было чувствительно к регистру, когда я понял, что все работает так, как ожидалось.

<?xml version="1.0" encoding="utf-8"?>
<configuration>
 <system.webServer>
  <httpProtocol>
   <customHeaders>
    <add name="Access-Control-Allow-Origin" value="*" />
    <add name="Access-Control-Allow-Methods" value="POST, GET, OPTIONS, PUT, DELETE" />
    <add name="Access-Control-Allow-Headers" value="content-type,soapaction,x-requested-with" />      
    </customHeaders>
   </httpProtocol>
        <handlers accessPolicy="Read, Execute, Script" />
 </system.webServer>
</configuration>

Мой код jQuery AJAX выглядит следующим образом.

var getNextJobId = function()
{
  var se = '';
  se = se + '<?xml version="1.0" encoding="UTF-8" standalone="no"?>';
  se = se + '<soap-env:Envelope xmlns:soap-env="http://www.w3.org/2003/05/soap-envelope">';
  se = se + '<soap-env:Body>';
  se = se + '<ebas:getNextJobIdRequest xmlns:ebas="http://www.ebasetech.com">';
  se = se + '<ebas:ORGCODE>' + plugin.settings.orgcode + '</ebas:ORGCODE>';
  se = se + '</ebas:getNextJobIdRequest>';
  se = se + '</soap-env:Body>';
  se = se + '</soap-env:Envelope>';
  $.ajax(
  {
    url: params.webserviceTargetUrl,
beforeSend: function(xhr)
{
  xhr.setRequestHeader("SOAPAction", "getNextJobId");
},
type: "POST",
dataType: "xml",
data: se,
crossDomain: true,
headers: {"X-Requested-With": "XMLHttpRequest"},
async: false,
success: function(xml)
{
  params.jobId =   $(xml).find("ebas\:JOBID").text();
},
failure: function(xml)
{
  params.webserviceFailure = $(xml).text();
},
      contentType: "charset=UTF-8"
});
}

Ответы

Ответ 1

"это было невозможно, потому что совместное использование ресурсов CORS или Cross Origin разрешало бы только вызовы типа jasonP (GET)."

CORS не ограничивается методами GET и не ограничивается вызовами стиля JSONP.

JSONP - это метод, который веб-разработчики использовали до того, как CORS был стандартизован, для выполнения запроса AJAX для хостов, отличных от того, который обслуживал страницу. JSONP работает, вставляя тег <script> на страницу. Для этого требуется участие сервера, как правило, путем переноса результатов JSON на вызов функции, названной в вызове AJAX с помощью параметра callback. См. Этот ответ: what-is-jsonp-all-about.

Как вы указали, JSONP ограничивается выполнением метода GET, потому что <script> выполняет только GET. У него есть и другие проблемы, например, невозможность обработки ошибок. Например, если возвращается ответ 400, script просто не выполняется браузером, а не выполняется обработчик ошибок JS для вызова AJAX.

CORS - это более новый стандарт. Он также требует участия сервера, поскольку он должен обрабатывать проверку перед флагом и использует дополнительные HTTP-заголовки, такие как: Access-Control-Allow-Origin, Access-Control-Allow-Methods и Access-Control-Allow-Headers, которые вы хорошо описали в редактировании на свой вопрос. Это не ограничивается методами GET. Скорее, он ограничен теми методами, которые указаны в результатах проверки перед полетом в заголовке Access-Control-Allow-Methods. CORS не требует обертывания результатов в функцию обратного вызова или любую другую корректировку результатов, а также обрабатывает ошибки и другие коды состояния. Для получения дополнительной информации см. Этот отличный обзор CORS.