Chrome扩展程序XHR收到403响应,除非从file:///启动

时间:2017-10-08 10:59:18

标签: javascript ajax google-chrome google-chrome-extension http-status-code-403

我正在开发一种Chrome扩展程序,该扩展程序使用fixer.io API进行货币汇率。

我通过一个简单的HTML页面开发扩展程序,我通过<script>标记包含我的JavaScript。当我想要实时测试时,我会构建它,转到chrome://extensions并点击加载解压缩的扩展程序

每当我从简单的HTML开发页面向API发出请求时,一切正常。但是,当我构建扩展并通过内容脚本发出请求时,我会从API收到403响应。

马上,我会说我在manifest.json中拥有这些权限:

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

以下是我加载脚本的方式(按照Makyen的要求):

"content_scripts": [
  {
    "run_at": "document_start",
    "css": [
      "main.css"
    ],
    "js": [
      "script.js"
    ],
    "matches": [
      "file:///*",
      "http://*/*",
      "https://*/*"
    ]
  }
]

如果我将请求更改为另一个(虚拟)API:

https://jsonplaceholder.typicode.com/posts?base=USD

一切都在无处不在,这意味着问题不在我的扩展程序设置中。

有问题的请求是:

https://api.fixer.io/latest?base=USD

它给出了错误:

GET https://api.fixer.io/latest?base=USD 403 (Forbidden)

以下是初始化请求的代码:

function currencyAPICall(currency, callback) {
    var url = "https://api.fixer.io/latest?base=" + currency,
        req = new XMLHttpRequest();

    req.addEventListener("load", function () {
        callback(data.rates);
    });

    req.open("GET", url, true);
    req.send(null);

    return req;
}

为了测试这一点,我让我的扩展程序在我的开发HTML文件中运行文件URL。 I.E.相同的代码运行两次,一次来自我的HTML页面,一次来自扩展名。结果如下:

comparing file and localhost requests from extension and script

除了使用file协议之外,我的扩展程序在任何地方都会收到403。如果它运行在localhost,StackOverflow,甚至是fixer.io网站本身都无关紧要。该请求使用https

求和

扩展内容脚本从任何地方的API调用接收403响应,除非在具有file协议的页面上运行,即使具有正确的清单权限。的为什么吗

如果我向另一个URL(前面提到的虚拟API)发出请求,我不会收到此错误。这是否意味着问题出在fixer.io服务器上?或者我需要设置某种标题?

我还在fixer.io的GitHub回购中写了一篇issue

修改

我注意到的一个主要差异是OriginReferer标头。如果它们中的任何一个都被设置或两者都没有,那么响应似乎是200。当我收到403回复时,Referer已设置,但Origin未设置。

修改

根据PredatorIWD的建议,从Event Page(又名背景页面)发出请求不会产生403.我得到正常的200 OK响应。

1 个答案:

答案 0 :(得分:1)

正如我在评论中所说,通常最好从background.js发送请求并使用消息传递将所需数据发送回内容脚本。

Heres是从后台脚本到内容脚本的简单一次性消息的示例:

从后台脚本:

chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
    chrome.tabs.sendMessage(tabs[0].id, {greeting: "hello"}, function(response) {
        console.log(response.farewell);
    });
});

到内容脚本:

chrome.runtime.onMessage.addListener( function(request, sender, sendResponse) {
    if (request.greeting == "hello"){
        sendResponse({farewell: "goodbye"});
    }
});

您可以阅读有关邮件传递的更多信息here