Отправка междоменного запроса AJAX/XDomainRequest в веб-службу

Я потратил много времени на чтение всех постов здесь и на других сайтах, и у меня есть следующий код:

    function post_cors(vars) {
        // cross domain AJAX posting - needs work to function in IE
        var successFunction = vars.success;
        var errorFunction = vars.error;
        var url = vars.url;
        var data = vars.data;

        if ($.browser.msie && window.XDomainRequest) {
            // CROSS DOMAIN AJAX FOR < IE10 (Doesn't work yet!)
            var xdr = new XDomainRequest();
            xdr.open("POST", url);
            xdr.send(JSON.stringify(data));
            xdr.onload = function () {
                // XDomainRequest doesn't provide responseXml, so if you need it:
                alert('Response: ' + xdr.responseText);
            };
        } else {
            $.ajax({ // proper AJAX for sensible browsers
                cache: false,
                dataType: "json",
                url: url,
                crossDomain: true,
                data: data,
                type: "POST",
                contentType: "application/json; charset=utf-8",
                success: function (data, textStatus, request) {
                    successFunction(data, textStatus, request);
                },
                error: function (data, textStatus, request) {
                    errorFunction(data, textStatus, request);
                }
            });
        };
    };

Функция вызывается следующим образом:

post_cors({
    'success': function (data) {
         doStuffWithResponse()
     },
     'url': SOME WEB SERVICE,
     'data': "{ 'para1': '" + para1 + "', 'para2': '" + para2+ "' }"
}); 

Он публикует стандартную кросс-доменную запись AJAX во взрослых браузерах, таких как Chrome и Safari, и отлично работает, в том числе на iPad и т. Д. Однако я не могу заставить эту вещь работать в IE < 10.

Соответствующий код:

var xdr = new XDomainRequest();
xdr.open("POST", url);
xdr.send(JSON.stringify(data));

Различные потоки на SO и другие предполагают, что это ДОЛЖНО работать, в том числе здесь: Как отправлять данные JSON в XDR, используя метод POST

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

Итак, я пробовал различные эксперименты;

Публикация в веб-метод без параметров;

<WebMethod()> _
Public Function HelloWorld() As String
    Return "Hello World"
End Function

Это похоже на работу при работе на локальных серверах, но не при добавлении на сервер, размещенный в сети. Я получаю 200 код успеха, но, кажется, не в состоянии увидеть ответ, ни через консоль IE, ни в Fiddler. Тот факт, что он работает "в автономном режиме", может быть в любом случае красной селедкой...?

Проводка в метод, который принимает параметры

<WebMethod()> _
Public Function TryThis(term as string) As String
    Return term
End Function

Это ВСЕГДА возвращает http 500 Ошибка с IE, но отлично работает во взрослых браузерах.

Я не получаю информацию об ошибках ни в Fiddle, ни в IE.

Последний показывает мне это как заголовки запроса:

Key Value
Request POST http://samtest.thinkka.com/api/Sam_ScriptService.asmx/HelloWorld HTTP/1.1
Accept  */*
Origin  http://localhost:63238
Accept-Language en-GB
Accept-Encoding gzip, deflate
User-Agent  Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)
Host    samtest.thinkka.com
Content-Length  108
Proxy-Connection    Keep-Alive
Pragma  no-cache

И заголовки ответа:

Key Value
Response    HTTP/1.1 500 Internal Server Error
Cache-Control   private
Content-Type    text/html; charset=utf-8
Server  Microsoft-IIS/7.5
X-AspNet-Version    4.0.30319
X-Powered-By    ASP.NET
Access-Control-Allow-Origin *
Access-Control-Allow-Methods    GET, POST
Access-Control-Allow-Headers    Content-Type
Date    Tue, 08 Oct 2013 10:24:29 GMT
Content-Length  4826

Response Body пусто, я не могу прочитать ни одного сообщения об ошибке, поэтому понятия не имею, где и почему эта ошибка возникает.

Я подозреваю, что проблемы связаны с POST или с данными формы?

Я попытался опубликовать данные как объект, а не как JSON.Stringified, но это не сработало, хотя я не ожидал

Все, что Fiddler, кажется, может сказать мне, что консоль IE не делает этого:

No Proxy-Authorization Header is present.
No Authorization Header is present.

Оба отображаются на вкладке "Auth", но также отображаются в Fiddler при использовании Chrome, который возвращает положительный ответ.

Я заметил, что Chrome публикует данные дважды, во время всего моего чтения я знаю, что это правильно (хотя не могу вспомнить, почему в данный момент), IE не делает, он только делает первый пост. Я думаю, что это правильно, хотя, как это функция AJAX?

Мой файл Web.Config добавляет правильные заголовки:

<customHeaders>
     <add name="Access-Control-Allow-Origin" value="*" />
     <add name="Access-Control-Allow-Methods" value="GET, POST" />
      <add name="Access-Control-Allow-Headers" value="Content-Type" />
</customHeaders>

Очевидно, что я знаю о проблемах междоменной области здесь, и следовал всем примерам, которые я могу найти, но я застрял сейчас... поэтому размещаю здесь.

Пожалуйста, не говорите мне не использовать веб-сервис ASMX, или что публикация кросс-доменов не разрешена, мне нужно решение сейчас!:-)

Автор оригинального вопроса в ссылке, размещенной выше, предполагает, что он решил свою проблему, обнаружив ошибку в ответе на его серверной стороне, но мой прекрасно работает во всем, кроме старых версий IE (кстати, в IE10 работает), поэтому я не может видеть, что это ошибка на стороне сервера - и, если это так, получение информации о Error 500 делает невозможным идентификацию.

2 ответа

Во-первых, вам нужно исправить свой код, чтобы он не пытался использовать XDomainRequest внутри IE10, который поддерживает CORS-for-XmlHttpRequest и устаревший объект XDomainRequest.

Затем необходимо обновить код на стороне сервера, чтобы он не возвращал ответ HTTP/500, когда в запросе отсутствует Content-Type: application/json заголовок. XDomainRequest не позволяет вам установить этот заголовок, и ваш сервер, похоже, ожидает его, когда решает, как проанализировать тело запроса.

Это может быть немного устаревшим, но я обнаружил, что IE8 на самом деле отправляет данные POST в двоичном потоке (или, возможно, просто текст). У меня были проблемы с попыткой декодировать форму POST, когда я узнал об этом. Быстрый однострочный текст в ASP.NET C# для получения этого контента:

string strContent = new System.Text.ASCIIEncoding().GetString(Context.Request.BinaryRead((int)Context.Request.InputStream.Length));

Расширьте это до вашего сердца.

Другие вопросы по тегам