Pergunta

Estou transferindo uma das minhas extensões do Firefox para o Chrome e estou enfrentando um pequeno problema com uma consulta de Ajax. O código a seguir funciona bem na extensão FF, mas falha com um status de "0" no 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;
}

Essa parte específica da extensão verifica o que está na área de transferência (outra questão do Chrome que eu já resolvi) e, se for um URL da imagem, envia uma solicitação de cabeça e verifica o cabeçalho da resposta "do tipo conteúdo" para garantir que seja uma imagem . Nesse caso, ele retornará verdadeiro, colando o texto da área de transferência em uma tag IMG. Caso contrário, se parecer um URL normal que não é uma imagem, ela a envolve em uma tag A. Se não é um URL, apenas faz uma pasta simples.

De qualquer forma, o URL que está sendo verificado é definitivamente uma imagem e funciona bem no FF, mas na função completa, xhr.status é "0" e status é "erro" quando a função é concluída. Aumentar o tempo limite para 10 segundos não ajuda. Verifiquei as imagens do teste devem voltar como "imagem/jpeg" ao executar:

curl -i -X HEAD <imageURL>

Eu também sei que deveria estar usando os retornos de chamada de sucesso e erro em vez de completos, mas eles também não funcionam. Alguma ideia?

Foi útil?

Solução

Como você descobriu Chris, em scripts de conteúdo, você não pode fazer nenhum XHRS de domínio cruzado. Você teria que fazê -los em uma página de extensão, como plano de fundo, pop -up ou mesmo opções para fazê -lo.

Para obter mais informações sobre a limitação do script de conteúdo, consulte:http://code.google.com/chrome/extensions/content_scripts.html

E para obter mais informações sobre a limitação do XHR, consulte:http://code.google.com/chrome/extensions/xhr.html

Outras dicas

Eu resolvi parte do problema, na verdade a maior parte. Primeiro, como Brennan e eu mencionamos ontem, eu precisava definir permissões em manifest.json.

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

Não é ideal fornecer permissões a todos os domínios, mas como as imagens podem ser hospedadas em qualquer domínio, ele terá que fazer, e terei que se proteger contra o XSS.

O outro problema é que o Chrome realmente bloqueia qualquer coisa na seção Content_scripts de fazer chamadas de Ajax, falhando silenciosamente. No entanto, não existe tal restrição no Background_Page, se você tiver um. Essa página pode fazer com que o Ajax seja chamado, e o Chrome possui uma API para permitir que seu script abra uma porta e passe solicitações para essa página em segundo plano. Alguém escreveu um script chamado Xhrproxy Como solução alternativa, e eu a modifiquei para obter o cabeçalho de resposta apropriado. Funciona!

Meu único problema agora é descobrir como fazer o script aguardar o resultado da chamada a ser definida no evento, em vez de apenas retornar imediatamente.

Verifique seu arquivo de manifesto. A extensão tem permissão para acessar esse URL?

Se ajudar ao seu segundo problema (ou qualquer outra pessoa): você pode enviar uma solicitação para sua página de segundo plano como:

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

A variável response pode ser tudo o que você quiser. Pode ser simplesmente um sucesso ou negar string. Você decide.

Na sua página de segundo plano, você pode adicionar um ouvinte:

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.
});

Com isso, você pode passar a resposta da sua solicitação de Ajax de volta ao seu script de conteúdo e fazer o que quiser com ele lá.

A resposta aceita está desatualizada.

Os scripts de conteúdo agora podem fazer xmlHttPrequests cruzados, assim como os scripts de fundo!

Os URLs preocupantes precisam ser permitidos no manifesto:

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

Você também pode usar expressões como:

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

para obter permissões mais gerais.

Aqui está o link para a documentação.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top