Вопрос

Я переношу одно из своих расширений Firefox на Chrome и сталкиваюсь с небольшой проблемой с AJAX-запросом.Следующий код отлично работает в расширении FF, но завершается сбоем со статусом "0" в Chrome.

function IsImage(url) {
    var isImage = false;
    var reImageContentType = /image\/(jpeg|pjpeg|gif|png|bmp)/i;
    var reLooksLikeImage = /\.(jpg|jpeg|gif|png|bmp)/i;

    if(!reLooksLikeImage.test(url)) 
    {
        return false;
    }

    var xhr = $.ajax({
        async: false,
        type: "HEAD",
        url: url,
        timeout: 1000,
        complete : function(xhr, status) {
            switch(status)
            {
                case "success":
                    isImage = reImageContentType.test(xhr.getResponseHeader("Content-Type"));
                    break;
            }
        },
    });

    return isImage;
}

Эта конкретная часть расширения проверяет, что находится в буфере обмена (еще одна проблема Chrome, которую я уже решил), и, если это URL-адрес изображения, оно отправляет запрос HEAD и проверяет заголовок ответа "Content-Type", чтобы убедиться, что это изображение.Если это так, он вернет true, вставив текст из буфера обмена в тег IMG.В противном случае, если он выглядит как обычный URL-адрес, который не является изображением, он заключает его в тег A.Если это не URL-адрес, он просто вставляет.

В любом случае, проверяемый URL-адрес определенно является изображением и отлично работает в FF, но в завершенной функции xhr.status равен "0", а status равен "ошибка" при завершении функции.Увеличение времени ожидания до 10 секунд не помогает.Я проверил, что тестовые изображения должны возвращаться как "image / jpeg" при запуске:

curl -i -X HEAD <imageURL>

Я также знаю, что я должен использовать обратные вызовы success и error вместо complete, но они тоже не работают.Есть какие-нибудь идеи?

Это было полезно?

Решение

Как вы уже поняли, Крис, в сценариях контента вы не можете выполнять какие-либо междоменные XHRS.Для этого вам нужно будет выполнить их на странице расширения, такой как фоновый режим, всплывающее окно или даже Опции.

Для получения дополнительной информации об ограничении скрипта содержимого, пожалуйста, обратитесь к:http://code.google.com/chrome/extensions/content_scripts.html

И для получения дополнительной информации об ограничении xhr, пожалуйста, обратитесь к:http://code.google.com/chrome/extensions/xhr.html

Другие советы

Я решил часть проблемы, на самом деле большую ее часть.Во-первых, как мы с Бреннаном упоминали вчера, мне нужно было установить разрешения в manifest.json.

"permissions": [
    "http://*/*",
    "https://*/*"
],

Не идеально давать разрешения каждому домену, но поскольку изображения могут размещаться из любого домена, это должно быть сделано, и мне придется защищаться от XSS.

Другая проблема заключается в том, что Chrome действительно блокирует выполнение AJAX-вызовов чем-либо в разделе content_scripts, что приводит к молчаливому сбою.Однако для background_page такого ограничения нет, если оно у вас есть.Эта страница может выполнять любые AJAX-вызовы по своему усмотрению, а в Chrome есть API, позволяющий вашему скрипту открывать порт и передавать запросы на эту фоновую страницу.Кто-то написал сценарий под названием XHRProxy в качестве обходного пути, и я изменил его, чтобы получить соответствующий заголовок ответа.Это работает!

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

Проверьте свой файл манифеста.Есть ли у расширения разрешение на доступ к этому URL-адресу?

Если это поможет решить вашу вторую проблему (или кого-либо еще):Вы можете отправить запрос на свою фоновую страницу следующим образом:

chrome.extension.sendRequest({var1: "var1value", var2: "value", etc}, 
 function(response) {
    //Do something once the request is done.
}); 

Переменная response может быть все, что ты захочешь, чтобы это было.Это может быть просто строка success или deny.Зависит от тебя.

На вашей фоновой странице вы можете добавить слушателя:

chrome.extension.onRequest.addListener(
function(request, sender, sendResponse) {
      // Do something here
      // Once done you can send back all the info via:
      sendResponse( anything you want here );

      // and it'll be passed back to your content script.
});

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

Принятый ответ устарел.

Скрипты контента теперь могут создавать межсайтовые XMLHttpRequests точно так же, как фоновые скрипты!

Соответствующие URL-адреса должны быть разрешены в манифесте:

{
  "name": "My extension",
  ...
  "permissions": [
    "http://www.google.com/"
  ],
  ...
}

Вы также можете использовать такие выражения, как:

"http://*.google.com/"
"http://*/"

чтобы получить более общие разрешения.

Вот ссылка на документацию.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top