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.