使用XMLHttpRequest从WebExtension访问休息服务时出错

时间:2017-04-22 23:57:51

标签: json rest amazon-web-services xmlhttprequest firefox-webextensions

我正在尝试从firefox WebExtension访问我在亚马逊AWS服务器上托管的休息服务。

我在manifest.json中注册了一个后台脚本,然后尝试访问该服务。

"background": {
    "scripts": ["OwnerLangBackground.js"]
},
"permissions": [
    "*://ec2-35-158-91-62.eu-central-1.compute.amazonaws.com:9000/*"
]

但是,XMLHttpRequest只返回错误,但我没有看到出错的地方。在研究这个问题时,我偶然发现了以下页面: https://mathiasbynens.be/notes/xhr-responsetype-json

用上面链接中的代码(略微修改过的)代码替换我自己的代码我现在有:

// OwnerLangBackground.js
console.log("OwnerLangBackground.js loaded");
var getJSON = function(url, successHandler, errorHandler) {
    var xhr = new XMLHttpRequest();
    xhr.open('get', url, true);
    xhr.onreadystatechange = function() {
        var status;
        var data;
        // https://xhr.spec.whatwg.org/#dom-xmlhttprequest-readystate
        if (xhr.readyState == 4) { // `DONE`
            status = xhr.status;
            if (status == 200) {
                data = JSON.parse(xhr.responseText);
                successHandler && successHandler(data);
            } else {
                errorHandler && errorHandler(status, xhr.responseText);
            }
        }
    };
    xhr.send();
};

/* BLOCK 1: removing the comments for this block works
getJSON('https://mathiasbynens.be/demo/ip', function(data) {
    console.log('Your public IP address is: ' + data.ip);
    console.log('Your response is: ', data);
}, function(status) {
    console.warn('Something went wrong.', status);
});
*/

/* BLOCK 2: removing the comments for this block, does not work
getJSON('http://ec2-35-158-91-62.eu-central-1.compute.amazonaws.com:9000/get-languages', function(data) {
    console.log('Your response is: ', data);
}, function(status) {
    console.warn('Something went wrong.', status);
});
*/

奇怪的是,激活BLOCK 1按预期工作(ip地址故意隐藏)。

    OwnerLangBackground.js loaded
    Your public IP address is: xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xx
    Your response is:  Object { ip: "xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:…" }

激活BLOCK 2会导致错误响应。

    OwnerLangBackground.js loaded
    Something went wrong. 0

但是,如果我直接使用curl调用这两个网址,它们都会返回有效的JSON:

    > curl https://mathiasbynens.be/demo/ip
    {"ip":"xxxx:xxxx:xxxx::xxx"}

    > curl http://ec2-35-158-91-62.eu-central-1.compute.amazonaws.com:9000/get-languages
    [{"language":"??"},{"language":"de"},{"language":"en"},{"language":"fr"},{"language":"it"}]

我已将调试输出添加到AWS服务器上的其他服务,我发现它已被调用。我还在运行WebExtension的本地机器上使用Wireshark跟踪WebExtension调用其他服务,我可以看到返回的JSON字符串,所以我猜这个错误发生在firefox / webextension中的某个地方,但我是总损失。

我考虑过的事情:

  • 清单中的权限:据我所知,我的aws-url的URL模式已正确添加。但是,即使我没有将url添加到权限
  • ,对mathiasbynens.be的调用仍然有效
  • 有效的通话使用https而不通话的通话使用http。这可能是原因吗?

有人能指出我正确的方向,以获得更多关于出错的反馈吗?我已经尝试在xhr请求中添加onerror回调。它被调用,但据我所知,它不提供更多信息。

更新: 我想出了两个更多的想法。使用curl -v为我提供了标题:

> curl -v http://ec2-35-158-91-62.eu-central-1.compute.amazonaws.com:9000/get-languages
* Hostname was NOT found in DNS cache
*   Trying 35.158.91.62...
* Connected to ec2-35-158-91-62.eu-central-1.compute.amazonaws.com (35.158.91.62) port 9000 (#0)
> GET /get-languages HTTP/1.1
> User-Agent: curl/7.38.0
> Host: ec2-35-158-91-62.eu-central-1.compute.amazonaws.com:9000
> Accept: */*
>
< HTTP/1.1 200
< Content-Type: application/json;charset=UTF-8
< Transfer-Encoding: chunked
< Date: Sun, 23 Apr 2017 06:43:42 GMT
<
* Connection #0 to host ec2-35-158-91-62.eu-central-1.compute.amazonaws.com left intact
[{"language":"??"},{"language":"de"},{"language":"en"},{"language":"fr"},{"language":"it"}]


> curl -v https://mathiasbynens.be/demo/ip
* Hostname was NOT found in DNS cache
*   Trying 2a01:1b0:7999:402::144...
* Connected to mathiasbynens.be (2a01:1b0:7999:402::144) port 443 (#0)
* successfully set certificate verify locations:
*   CAfile: none
  CApath: /etc/ssl/certs
* SSLv3, TLS handshake, Client hello (1):
* SSLv3, TLS handshake, Server hello (2):
* SSLv3, TLS handshake, CERT (11):
* SSLv3, TLS handshake, Server key exchange (12):
* SSLv3, TLS handshake, Server finished (14):
* SSLv3, TLS handshake, Client key exchange (16):
* SSLv3, TLS change cipher, Client hello (1):
* SSLv3, TLS handshake, Finished (20):
* SSLv3, TLS change cipher, Client hello (1):
* SSLv3, TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
* Server certificate:
*        subject: OU=Domain Control Validated; OU=PositiveSSL Wildcard; CN=*.mathiasbynens.be
*        start date: 2015-07-28 00:00:00 GMT
*        expire date: 2018-08-12 23:59:59 GMT
*        subjectAltName: mathiasbynens.be matched
*        issuer: C=GB; ST=Greater Manchester; L=Salford; O=COMODO CA Limited; CN=COMODO RSA Domain Validation Secure Server CA
*        SSL certificate verify ok.
> GET /demo/ip HTTP/1.1
> User-Agent: curl/7.38.0
> Host: mathiasbynens.be
> Accept: */*
>
< HTTP/1.1 200 OK
< Date: Sun, 23 Apr 2017 06:44:16 GMT
* Server Apache is not blacklisted
< Server: Apache
< Access-Control-Allow-Origin: *
< Strict-Transport-Security: max-age=15768000; includeSubDomains
< Vary: Accept-Encoding
< Cache-Control: max-age=0
< Expires: Sun, 23 Apr 2017 06:44:16 GMT
< X-UA-Compatible: IE=edge
< X-Content-Type-Options: nosniff
< X-Frame-Options: DENY
< X-XSS-Protection: 1; mode=block
< Transfer-Encoding: chunked
< Content-Type: application/json;charset=UTF-8
<
* Connection #0 to host mathiasbynens.be left intact
{"ip":"xxxx:xxxx:xxxx::xxx"}

突出的一个区别是我的休息服务的响应缺少Transfer-EncodingAccess-Control-Allow-Origin?标题,所以我会考虑添加这些标题。

但是,如果有人提示如何获取有关XmlHttpRequest出错的更多错误信息,我会很高兴听到它。

1 个答案:

答案 0 :(得分:0)

好吧,似乎丢失的Access-Control-Allow-Origin?标题是我问题的根源。

我现在通过添加另一个方法参数HttpServletResponse response然后在该参数上调用setHeader()来更改Spring-RestControllers中的所有方法。

@RequestMapping("/get-languages")
public @ResponseBody List<Language> getLanguages(HttpServletResponse  response) {
    response.setHeader("Content-Type", "application/json;charset=UTF-8");
    response.setHeader("Access-Control-Allow-Origin", "*");
    return languageRepository.findAll();
}

现在,我的WebExtension可以使用XmlHttpRequest成功使用此休息服务。

如果在firefox的调试或js控制台的某处可以看到这些信息(缺少CORS标题)会有所帮助,所以如果有人能告诉我我怎么能看到这个,我仍然会欣赏一个提示