Я портирую одно из своих расширений 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 изображения, это отправляет ГЛАВНЫЙ запрос и проверяет заголовок ответа "Типа контента", чтобы быть уверенным, что это - изображение. Если так, это возвратит true, вставляя текст буфера обмена в теге img. Иначе, если это похоже на нормальный URL, это не изображение, это обертывает его в тег. Если это не URL, это просто делает простую вставку.
Так или иначе проверяемый URL является определенно изображением и хорошо работает в FF, но в полной функции, xhr.status "0", и состояние является "ошибкой", когда функция завершается. Повышение тайм-аута к 10 секундам не помогает. Я проверил, что тестовые изображения должны возвратиться как "image/jpeg" при выполнении:
curl -i -X HEAD <imageURL>
Я также знаю, что должен использовать успех и ошибочные обратные вызовы вместо полного, но они не работают также. Какие-либо идеи?
Как вы поняли, Крис, в Content Scripts вы не можете делать кросс-доменные XHR. Для этого необходимо сделать их на странице расширения, например, в фоновом режиме, всплывающем окне или даже на странице настроек.
Дополнительные сведения об ограничении сценария содержимого см. в разделе: http://code.google.com/chrome/extensions/content_scripts.html
А для получения более подробной информации об ограничении xhr, пожалуйста, обратитесь к следующему: http://code.google.com/chrome/extensions/xhr.html
Проверьте файл манифеста. Есть ли у расширения разрешение на доступ к этому 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-запроса обратно в ваш контент-скрипт и делать с ним все, что захотите.
Я решил часть проблемы, на самом деле большую ее часть. Во-первых, как мы с Бреннан упомянули вчера, мне нужно было установить разрешения в файле манифест.json.
"permissions": [
"http://*/*",
"https://*/*"
],
Это не идеально - давать разрешения на каждый домен, но поскольку изображения могут размещаться на любом домене, это придется сделать, и мне придется защищаться от XSS.
Другая проблема заключается в том, что Chrome действительно блокирует все, что находится в разделе content_scripts, от совершения AJAX-звонков, беззвучно терпя неудачу. Однако такого ограничения на странице background_page не существует, если оно у вас есть. Эта страница может делать любые AJAX-вызовы, которые она хочет, и Chrome имеет API, чтобы позволить вашему скрипту, чтобы открыть порт и передать запросы на эту фоновую страницу. Кто-то написал скрипт под названием XHRProxy в качестве обходного пути, и я модифицировал его, чтобы получить соответствующий заголовок ответа. Это работает!
Моя единственная проблема сейчас в том, как заставить скрипт ждать результата вызова, который будет установлен в событии, а не просто возвращаться немедленно.
.