Вызов jQuery .ajax для bit.ly возвращает результаты в IE, но не в FF или Chrome

Я пытаюсь вызвать службу сокращения URL-адресов bit.ly, используя jQuery с вызовом .ajax.

обновление Интересно, это проблема междоменной безопасности? Я звоню с mysite.com на bit.ly

<html><head>
<script type="text/javascript" src="http://www.twipler.com/settings/scripts/jquery.1.4.min.js"></script>
<script type="text/javascript">
jQuery.fn.shorten = function(url) 
{ 
  var resultUrl = url;

  $.ajax(
  {
     url: "http://api.bit.ly/shorten?version=2.0.1&login=twipler&apiKey=R_4e618e42fadbb802cf95c6c2dbab3763&longUrl=" + url,
     async: false,
     dataType: 'json',
     data: "",
     type: "GET",
     success: 
     function (json) {  resultUrl = json.results[url].shortUrl; } 
     });

   return resultUrl;
} ;
</script></head><body>
<a href="#" 
      onclick="alert($().shorten('http://amiconnectedtotheinternet.com'));">
      Shorten</a>   </body>    </html>

Это работает в IE8, но не работает в FireFox (3.5.9) и в Chrome. В обоих случаях «json» имеет значение null.

Заголовки в IE8

GET http://api.bit.ly/shorten?ver..[SNIP]..dtotheinternet.com HTTP/1.1
Accept: application/json, text/javascript, */*
Accept-Language: en-US
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0;
      SLCC2; .NET CLR 2.0.50727; Media Center PC 6.0; InfoPath.2; 
     .NET CLR 1.1.4322; .NET CLR 3.5.30729; .NET CLR 3.0.30729)
Host: api.bit.ly
Connection: Keep-Alive

Заголовки в Chrome

GET http://api.bit.ly/shorten?versio..[SNIP]..nectedtotheinternet.com HTTP/1.1
Host: api.bit.ly
Connection: keep-alive
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/532.5 
    (KHTML, like Gecko) Chrome/4.1.249.1045 Safari/532.5
Origin: file://
Accept: application/json, text/javascript, */*
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3 

Таким образом, единственное очевидное отличие состоит в том, что Chrome отправляет «Origin: file://», и я понятия не имею, как это остановить.


person Dead account    schedule 08.04.2010    source источник
comment
Обратите внимание, что вы не должны никогда делать это в реальном мире. Выполняя сокращение в браузере, вы раскрываете свои API-ключи всему миру. С этими ключами API любой может сокращать от вашего имени. Вы всегда должны обращаться с ключами API и токенами OAuth так же, как с паролями. Дополнительную информацию можно найти в нашем рекомендациях.   -  person SeanOC    schedule 24.04.2014


Ответы (2)


Используйте Fiddler для проверки фактической полезной нагрузки запроса и ответа от службы bit.ly. Сравните запрос/ответ IE с запросом Chrome, чтобы определить, что отличается.

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

Обновление: Таким образом, заголовки HTTP действительно выявили проблему. :-)

Заголовок Origin добавляется агентом пользователя, когда он хочет предложить веб-сайт, который запрос является перекрестным запросом. Судя по всему, Chrome добавил поддержку для этот заголовок недавно. И, конечно же:

Детали заголовка Origin все еще дорабатываются. Мы будем обновлять реализацию в Google Chrome по мере развития спецификации на основе отзывов от Mozilla, а также от сообществ W3C и IETF в целом.

Может оказаться, что в настоящее время вы ничего не можете сделать, чтобы запретить Chrome отправлять этот заголовок. Кстати, кажется, что заголовок Origin был впервые представлен в Firefox 3.6, и я подозреваю, что вы один из тех людей, которые используют все последние и лучшие из всех браузеров. :-)

Кстати, XMLHttpRequest имеет междоменные ограничения. Итак, мне интересно, не использует ли jQuery.Ajax новый XDomainRequest в IE8 вместо XMLHttpRequest.

Но вернемся к вашей проблеме - на данный момент все указывает на то, что единственным доступным решением было бы сделать вызов Ajax на ваш сайт и сделать вызов bit.ly с вашего сервера. Не оптимально, я знаю...

person Franci Penov    schedule 08.04.2010
comment
Спасибо за советы, я попробую их позже. Интересно, что если вы просто вставите URL-адрес запроса в IE/FF/Chrome, вы получите правильный ответ :( - person Dead account; 08.04.2010
comment
Я бы предположил, что указанный адрес (по крайней мере, IE точно) во всех браузерах правильно кодирует URL-адрес параметра. Однако я не удивлюсь, если реализация XMLHttpRequest в Firefox и Chrome ожидает, что вызывающий код сделает это и передаст URL-адрес, как он его увидит. На самом деле это может быть преднамеренным, согласно URI RFC (3896 или 3986 - я всегда забываю точное число), параметры запроса разрешены в середине пути, поэтому нет 100% способа узнать, является ли URL-адрес в параметрах не часть пути и не должны быть закодированы. - person Franci Penov; 08.04.2010
comment
Я добавил плагин URLEncode и закодировал URL. До сих пор нет радости. Я мог бы быстрее пойти на обходной путь и позвонить на bit.ly с моего веб-сайта и позвонить на мой веб-сайт с jQuery. - person Dead account; 08.04.2010
comment
Вы смотрели на фактический HTTP-запрос/ответ в Fiddler? Как я уже сказал, немного о кодировке параметра URL было диким предположением. Вы должны попытаться выяснить, в чем именно разница между вызовами IE и Firefox, чтобы выяснить реальную проблему. - person Franci Penov; 08.04.2010
comment
Обновил вопрос с заголовками. Все равно никуда не денешься. Добавлю награду завтра. - person Dead account; 09.04.2010
comment
Спасибо за помощь и отличное объяснение. Я постоянно обновляю Chrome и FF. Я отправлю запрос на мой сайт, что на самом деле облегчает жизнь (короче говоря, это приложение для твиттера, и я хочу сделать вариант для bit.ly is.gd и т. д.) Большое спасибо - person Dead account; 10.04.2010

Быстрый и ленивый способ заставить это работать — использовать JSONP.

i.e.

$.ajax(
{
     url: Request,
     async: false,
     dataType: 'jsonp',
     data: "",
     type: "GET",
     success: 
     function (json) {  console.log(json.data.url); } 
});

Должно работать во всем.

person Chris McKee    schedule 14.07.2010