Ошибка вызова jQuery.ajax внутри расширения Chrome - PullRequest
9 голосов
/ 23 декабря 2009

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

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», а состояние - «ошибка», когда функция завершается. Увеличение таймаута до 10 секунд не помогает. Я убедился, что тестовые изображения должны возвращаться как «image / jpeg» при запуске:

curl -i -X HEAD <imageURL>

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

Ответы [ 4 ]

11 голосов
/ 24 декабря 2009

Как вы выяснили, Крис, в Сценариях содержания вы не можете делать никаких междоменных XHR. Вы должны сделать это на странице расширения, такой как Фон, Всплывающее окно или даже Параметры, чтобы сделать это.

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

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

5 голосов
/ 24 декабря 2009

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

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

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

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

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

5 голосов
/ 24 декабря 2009

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

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

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

Переменная response может быть любой, какой вы хотите. Это может быть просто успех или отрицание строки. До вас.

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

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-запроса обратно в ваш контент-скрипт и делать там все, что вы хотели.

2 голосов
/ 11 сентября 2013

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

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

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

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

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

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

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

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

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