使用 XMLHttpRequest 从 WebExtension 访问休息服务时出错
Error when accessing rest service from WebExtension using XMLHttpRequest
我正在尝试从 firefox WebExtension 访问我托管在亚马逊 AWS 服务器上的休息服务。
我在 manifest.json 中注册了一个后台脚本,然后尝试访问该服务。
"background": {
"scripts": ["OwnerLangBackground.js"]
},
"permissions": [
"*://ec2-35-158-91-62.eu-central-1.compute.amazonaws.com:9000/*"
]
但是,XMLHttpRequest return只是一个错误,但我看不出哪里出了问题。在研究这个问题时,我偶然发现了以下页面:
https://mathiasbynens.be/notes/xhr-responsetype-json
将我自己的代码替换为上述代码的(稍作修改的)副本 link 我现在有:
// 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
调用两个 URL,它们都 return 有效 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 字符串被 returned,所以我猜错误发生在 firefox/the webextension 的某处,但我完全不知所措。
我考虑过的事情:
- 清单中的权限:据我所知,我的 aws-url 的 URL 模式已正确添加。但是,即使我没有将 url 添加到权限
,对 mathiasbynens.be 的调用仍然有效
- 有效的调用使用https,无效的调用使用http。这可能是原因吗?
任何人都可以指出正确的方向以获得更多关于错误的反馈吗?我试过向 xhr 请求添加 onerror
回调。它被称为但据我所知没有提供更多信息。
更新:
我又想出了两个主意。使用 curl -v
为我提供了 headers:
> 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-Encoding
和 Access-Control-Allow-Origin?
headers,所以我会考虑添加这些。
不过,如果有人提示如何获取有关 XmlHttpRequest 问题的更多错误信息,我将很高兴听到。
好的,看来缺少 Access-Control-Allow-Origin?
header 是我问题的根源。
我现在已经更改了 Spring-RestControllers 中的所有方法,方法是添加另一个方法参数 HttpServletResponse response
,然后对该参数调用 setHeader()
。
@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
.
成功地使用这个 rest 服务
如果此信息(缺少 CORS header)在 firefox 的调试或 js 控制台中的某处可见,那将会很有帮助,所以如果有人能告诉我我是如何看到这个的,我仍然感谢您的提示。
我正在尝试从 firefox WebExtension 访问我托管在亚马逊 AWS 服务器上的休息服务。
我在 manifest.json 中注册了一个后台脚本,然后尝试访问该服务。
"background": {
"scripts": ["OwnerLangBackground.js"]
},
"permissions": [
"*://ec2-35-158-91-62.eu-central-1.compute.amazonaws.com:9000/*"
]
但是,XMLHttpRequest return只是一个错误,但我看不出哪里出了问题。在研究这个问题时,我偶然发现了以下页面: https://mathiasbynens.be/notes/xhr-responsetype-json
将我自己的代码替换为上述代码的(稍作修改的)副本 link 我现在有:
// 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
调用两个 URL,它们都 return 有效 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 字符串被 returned,所以我猜错误发生在 firefox/the webextension 的某处,但我完全不知所措。
我考虑过的事情:
- 清单中的权限:据我所知,我的 aws-url 的 URL 模式已正确添加。但是,即使我没有将 url 添加到权限 ,对 mathiasbynens.be 的调用仍然有效
- 有效的调用使用https,无效的调用使用http。这可能是原因吗?
任何人都可以指出正确的方向以获得更多关于错误的反馈吗?我试过向 xhr 请求添加 onerror
回调。它被称为但据我所知没有提供更多信息。
更新:
我又想出了两个主意。使用 curl -v
为我提供了 headers:
> 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-Encoding
和 Access-Control-Allow-Origin?
headers,所以我会考虑添加这些。
不过,如果有人提示如何获取有关 XmlHttpRequest 问题的更多错误信息,我将很高兴听到。
好的,看来缺少 Access-Control-Allow-Origin?
header 是我问题的根源。
我现在已经更改了 Spring-RestControllers 中的所有方法,方法是添加另一个方法参数 HttpServletResponse response
,然后对该参数调用 setHeader()
。
@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
.
如果此信息(缺少 CORS header)在 firefox 的调试或 js 控制台中的某处可见,那将会很有帮助,所以如果有人能告诉我我是如何看到这个的,我仍然感谢您的提示。