Помогите, пожалуйста, протестировать проблему CORS в Firefox jQuery ajax, когда 401 - PullRequest
6 голосов
/ 20 июля 2010

это сводит меня с ума.

jQuery 1.4.2, windows XP sp3

Вот мой тест.

Загрузка Firefox 3.5 +

http://plungjan.name/test/testcors.html

работает

Сохраните файл на жесткий диск и запустите оттуда

Из моего офиса внешний работает, а внутренний не

Что такоетакже интересно то, что я не могу запустить оба сразу.

Справочная информация: я делаю GET для внутренней веб-службы, которая использует CORS .Пожалуйста, НЕ отправляйте любые ответы о том, что FF не обрабатывает междоменный запрос, когда это делается начиная с версии 3.5, как подробно здесь и здесь

Этоработает в IE8 и FF3.6.6 с одного сервера на другой и теперь почти из файловой системы (file: ///) в службу. Только из файловой системы и только , когда FF 3.6.6 необходимо согласовать (пользователь уже авторизован, авторизован и отправляет учетные данные!) не яполучить данные после переговоров.jQuery xhr возвращает статус 0, а data / responseText или что-то еще, что мне кажется, jQuery реагирует и сохраняет xhr из 401, а не из 200 OK позже

Вот результат, который я получаю в конце сообщениякогда я оповещаю объект XHR:

Status:success 
Data:[] 
XHR: 
some native functions,
readyState:4 
status:0
responseXML:null 
responseText: 
withCredentials:true

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

Таким образом, связь происходит следующим образом:

GET /restapplicationusingcors/authenticationneeded-internal/someid
Accept: application/json
Accept-Language: en
.
.
Origin: null
Cookie: LtpaToken=...

возврат

HTTP/1.1 401 Unauthorized
Server: Apache
Pragma: No-cache
Cache-Control: no-cache
Expires: Thu, 01 Jan 1970 01:00:00 CET
WWW-Authenticate: Negotiate
Connection: close
Transfer-Encoding: chunked
Content-Type: text/html

Затем FF отправляет

GET /restapplicationusingcors/authenticationneeded-internal/someid HTTP/1.1
Host: myhost.myintranet.bla
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.6) Gecko/20100625 Firefox/3.6.6
Accept: application/json
Accept-Language: en
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 115
Connection: keep-alive
Origin: null
Cookie: LtpaToken=....
Authorization: Negotiate ....

и получает файл, который мне нужен, но не может получить в FF:

HTTP/1.1 200 OK
Date: Tue, 20 Jul 2010 12:08:39 GMT
Pragma: No-cache
Cache-Control: no-cache, max-age=600, s-maxage=3600
Expires: Thu, 01 Jan 1970 01:00:00 CET
X-Powered-By: ...
Content-Disposition: inline;filename=nnnnnn.json
Content-Language: en
Access-Control-Allow-Origin: ...
Keep-Alive: timeout=6, max=70
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: application/json;charset=UTF-8

ДАННЫЕ, ОТПРАВЛЕННЫЕ С СЕРВЕРА, НЕ В ОБЪЕКТЕ XHR

Вот мой код

function getJSON(url,func,lang) {
  accept = 'application/json';
  lang=lang?lang:"*";
  // gruesome hack to handle that APPENDS the mime header to */* !!!
  // NOW HANDLED by first setting Accept to "" !!! 
//  if ($.browser.msie && url.indexOf('serveAsMime')==-1)  {
//    url+= '?serveAsMime='+accept;
//  }
  if (currentRequest != null) currentRequest.abort();
  var requestObjectJSON =   {
    url    : url,
//    dataType: "json",
    method : 'get',
    beforeSend: function(xhr){
      xhr.setRequestHeader('Accept', ""); // IE hack
      xhr.setRequestHeader('Accept', accept);
      xhr.setRequestHeader('Accept-Language', lang);
      if (url.indexOf('-internal') !=-1) {
        try {
          xhr.withCredentials = true;
          alert('set credentials') 
        }
        catch(e) {
          alert('cannot set xhr with credentials')
        }
      }
    },

    success: function(data,status,xhr) {
      var responseText = xhr.responseText;
      var responseJSON = xhr.responseJSON;


      var t = "";
      try{
        for (var o in xhr) t += '\n'+o+':'+xhr[o];
      }
      catch(e) {
        if (e.message.indexOf('.channel')==-1)alert(e.message);
      }
      alert('Status:'+status+'\nData:['+data+']\nXHR:'+t);
      func(responseText);
    },
  }
  currentRequest = $.ajax(requestObjectJSON);
}

Ответы [ 4 ]

3 голосов
/ 31 июля 2010

Это удар в темноте, поскольку я не до конца понимаю вашу проблему, но я думаю, что у вас могут быть проблемы с file: URL-адресами, которые не рассматриваются как имеющие любого происхождения. Я не уверен, что даже возможно авторизовать CORS по URL-адресу файла.

1 голос
/ 27 мая 2014

Для работы CORS с защищенными сервисами необходимо выполнить следующие условия:

Общая конфигурация для Apache:

# Static content:
SetEnvIf      Request_URI     ".*"                            no-jk
# RESTful service:
SetEnvIf      Request_URI     "^/backend/"                    !no-jk
SetEnvIf      Request_Method  "OPTIONS"                       no-jk
# Fallback value:
SetEnv        http_origin     "*"
SetEnvIf      Origin          "^https?://(localhost|.*\.myconpany\.org)(:[0-9]+)?$" http_origin=$0

Header        set Access-Control-Allow-Credentials    "true"
Header        set Access-Control-Allow-Origin         "%{http_origin}e"
Header        set Access-Control-Allow-Methods        "GET,POST,PUT,DELETE"
Header        set Access-Control-Allow-Headers        "Content-Type, Accept"

JkMount /* loadbalancer
1 голос
/ 08 июня 2012

Таким образом, вам нужно установить предварительный фильтр ajax в вашей модели / коллекции, чтобы использовать CORS.В противном случае он не отправляет cookie.

$.ajaxPrefilter( function( options, originalOptions, jqXHR ) {
    options.xhrFields = {
      withCredentials: true
    };
});

Я поместил это в функцию инициализации модели / коллекции.

0 голосов
/ 27 мая 2014

CORS с file://

Если у вас есть проблемы с разрешением происхождения из протокола file://, в соответствии с Концепцией веб-происхождения это следует сделать так же, как и любой другойпроисхождение. Мне не удалось найти информацию о поддержке браузера, но я думаю, что каждый браузер, поддерживающий CORS, тоже поддерживает этот вариант.

Концепция веб-происхождения сообщает нам следующее о схеме URI файла.:

   4.  If uri-scheme is "file", the implementation MAY return an
       implementation-defined value.

          NOTE: Historically, user agents have granted content from the
          file scheme a tremendous amount of privilege.  However,
          granting all local files such wide privileges can lead to
          privilege escalation attacks.  Some user agents have had
          success granting local files directory-based privileges, but
          this approach has not been widely adopted.  Other user agents
          use globally unique identifiers for each file URI, which is
          the most secure option.

Согласно wikipedia домен по схеме URI файла является localhost.Он пропускается адресной строкой, но я не думаю, что он пропускается в заголовках разрешенного источника.Так что, если ваша реализация браузера допускает происхождение с помощью схемы файлового URI, то вы должны добавить file://localhost к разрешенным источникам, и после этого все должно работать правильно.

Вот как это должно работать, теперь соответствовать реальности:

  • Я тестировал с текущим Firefox 29.0.1, и он не работал.Однако протокол file:// преобразуется в null origin этой реализацией.Таким образом, Firefox null работает.Я попытался с более широким списком доменов, но мне не удалось разрешить несколько доменов.Похоже, что Firefox в настоящее время не поддерживает список с несколькими доменами.
  • Я тестировал с Chrome 35.0.1916, он работает так же, как Firefox.
  • Я тестировал с MSIE 11.0.9600,По запросу из файлового протокола всегда отображается кнопка allow blocked content, даже если не разрешено нулевое происхождение.В других доменах он работает так же, как и в предыдущих браузерах.

Базовая аутентификация HTTP:

Часть учетных данных, которую я опробовал с базовой аутентификацией PHP и HTTP.

http://test.loc
Отображается :-) при входе в систему и :-( при несанкционированном доступе.

<?php

function authorized()
{
    if (empty($_SERVER['PHP_AUTH_USER']) || empty($_SERVER['PHP_AUTH_PW']))
        return false;
    return ($_SERVER['PHP_AUTH_USER'] == 'username' && $_SERVER['PHP_AUTH_PW'] == 'password');
}

function unauthorized()
{
    header('HTTP/1.1 401 Unauthorized');
    header('WWW-Authenticate: Basic realm="Restricted Area"');
    echo '<a href="http://test.loc">:-(</a>';
}

if (!isset($_GET['logout']) && authorized()) {
    echo '<a href="http://test.loc?logout=1">:-)</a>';
} else
    unauthorized();

Таким образом, этот код изменяет местоположение при входе и выходе из системы.

Междоменный CORS с базовой аутентификацией HTTP

http://todo.loc
Получает содержимое http://test.loc с междоменным XHR и отображает его.

cross domain ajax<br />
<script>
    var xhr = new XMLHttpRequest();
    xhr.open('GET', "http://test.loc", true);
    xhr.withCredentials = true;
    xhr.onreadystatechange = function (){
        if (xhr.readyState==4) {
            document.body.innerHTML += xhr.responseText;
        }
    };
    xhr.send();
</script>

Требуются заголовки по http://test.loc:

Access-Control-Allow-Origin: http://todo.loc
Access-Control-Allow-Credentials: true

Кросс-схема CORS с базовой аутентификацией HTTP

файл:///path/x.html
Получает содержимое http://test.loc с кросс-схемой XHR и отображает его.

cross scheme ajax<br />
<script>
    var xhr = new XMLHttpRequest();
    xhr.open('GET', "http://test.loc", true);
    xhr.withCredentials = true;
    xhr.onreadystatechange = function (){
        if (xhr.readyState==4) {
            document.body.innerHTML += xhr.responseText;
        }
    };
    xhr.send();
</script>

Требуются заголовки от http://test.loc:

Access-Control-Allow-Origin: null
Access-Control-Allow-Credentials: true

Вывод:

Я протестировал CORS с несколькими листами с учетными данными из file://, и он довольно хорошо работает в Firefox, Chrome и MSIE.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...