我遇到了在网络中两个不同域之间向Nodejs服务器发出ExtJS AJAX请求的问题,并会感谢任何帮助。从ExtJS客户端尝试来自http和https时响应失败,但是来自我本地的通过http的Curl返回200 OK和正确的数据。我们正在处理内容类型application/json
。
ExtJS onReady函数启用了CORS:
Ext.onReady(function () {
Ext.Ajax.cors = true;
Ext.Ajax.useDefaultXhrHeader = false;
... (code removed)
})
来自我的ExtJS客户端的一个已知工作URL的测试,它将正确创建ExtJS数据存储区(带回200 OK):
Ext.create('Ext.data.Store', {
id : 'countryStore',
model : 'country',
autoLoad : true,
autoDestroy: true,
proxy: {
type: 'rest',
url : 'https://restcountries.eu/rest/v1/all',
},
reader: {
type : 'json',
headers: {'Accept': 'application/json'},
totalProperty : 'total',
successProperty: 'success',
messageProperty: 'message'
}
});
但是,当通过
向Nodejs服务器尝试请求时 http
:
Ext.create('Ext.data.Store', {
id : 'circuits',
model : 'circuit',
autoLoad : true,
autoDestroy: true,
proxy: {
type: 'rest',
url : 'http://ourNodeJsServerDomain:5500/v3/circuits',
},
reader: {
type : 'json',
headers: {'Accept': 'application/json'},
totalProperty : 'total',
successProperty: 'success',
messageProperty: 'message'
}
});
在Chrome控制台中返回以下内容:
Mixed Content: The page at 'https://ourExtJsDevClientSide' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint 'http://ourNodeJsServerDomain:5500/v3/circuits?_dc=1430149427032&page=1&start=0&limit=50'. This request has been blocked; the content must be served over HTTPS.
现在,尝试超过https
时:
Firefox显示:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://ourNodeJsServerDomain:5500/v3/circuits?_dc=1430151516741&page=1&start=0&limit=50. This can be fixed by moving the resource to the same domain or enabling CORS.
并且请求标题没有显示" application / json",这是一个问题吗?:
Accept
text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding
gzip, deflate
Accept-Language
en-US,en;q=0.5
Host
ourNodeJsServerDomain:5500
Origin
https://ourExtJsDevClientSide
Referer
https://ourExtJsDevClientSide
User-Agent
Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:37.0) Gecko/20100101 Firefox/37.0
然后我尝试使用Curl来查看帮助调试的响应
http
上的给出200 OK响应,但即使我们将其定义为"*"
,Access-Control-Allow-Origin仍未定义:
curl http://ourNodeJsServerDomain:5500/v3circuits?_limit=1 -v
> GET /v3/circuits?_limit=1 HTTP/1.1
> User-Agent: curl/7.37.1
> Host: ourNodeJsServerDomain:5500
> Accept: */*
>
< HTTP/1.1 200 OK
< X-Powered-By: Express
< Access-Control-Allow-Origin: undefined
< Access-Control-Allow-Methods: GET
< Access-Control-Allow-Headers: Content-Type
< Content-Type: application/json; charset=utf-8
< Content-Length: 1126
< ETag: W/"MlbRIlFPCV6w7+PmPoVYiA=="
< Date: Mon, 27 Apr 2015 16:24:18 GMT
< Connection: keep-alive
<
[
{ *good json data returned here* } ]
然后当我尝试通过https
curl https://ourNodeJsServerDomain:5500/v3/circuits?_limit=1 -v
* Server aborted the SSL handshake
* Closing connection 0
curl: (35) Server aborted the SSL handshake
我们在Nodejs服务器上启用了CORS:
router
.all('*', function(req, res, next){
res.setHeader('Content-Type', 'application/json');
// res.setHeader("Access-Control-Allow-Origin", req.headers.origin);
// console.log('\n\nreq.headers.origin ===================== ' + req.headers.origin);
//I have tried allowing all * via res.SetHeader and res.header and neither is defining the Access-Control-Allow-Origin properly when curling
//res.setHeader("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Origin", "*");
// res.header("Access-Control-Allow-Headers", "X-Requested-With");
res.header('Access-Control-Allow-Methods', 'GET');
res.header('Access-Control-Allow-Headers', 'Content-Type');
我试图在我的思考过程中详细说明,我愿意尝试新的方法来确定如何理解和解决这个问题。
*解决方案*
问题是来自浏览器的混合内容。我们的客户端UI在https(安全)上,而我们从nodejs服务器请求http(不安全)内容。我们需要允许我们的nodejs服务器在https上运行
我们generated SSL certifications并将它们实现到我们的nodejs服务器上。
在nodejs代码中,我们使用CORS模块启用CORS并运行http和https服务器:
// enable CORS for all requests
var cors = require('cors');
app.use(cors());
// for certifications
var credentials = {
key: fs.readFileSync('our.key'),
cert: fs.readFileSync('our.crt')
};
var httpServer = http.createServer(app);
var httpsServer = https.createServer(credentials, app);
httpServer.listen(port, function() {
console.log('HTTP server listening on port ' + port);
});
httpsServer.listen(httpsPort, function() {
console.log('HTTPS server listening on port ' + httpsPort);
});
答案 0 :(得分:4)
您的服务器中似乎存在CORS和HTTPS问题......您应该尝试this middleware作为CORS部分,并在首先以原始HTTP访问页面时使其工作。据我所知,您必须use different ports才能使用HTTP和HTTPS。而且您可能还需要启用CORS credentials。正如我所说,我认为你最好先在HTTP中使用它;)
然后,在Ext部分,如评论中已经提到的那样,您应该禁用默认标头(或者您必须让服务器接受所有这些标头;请参阅this answer的第一条评论)。但是您需要在代理上执行,因为Ext.Ajax
中的apparently it replaces the global setting。
所以,像这样:
Ext.create('Ext.data.Store', {
id : 'countryStore',
model : 'country',
autoLoad : true,
autoDestroy: true,
proxy: {
type: 'rest',
url : 'https://restcountries.eu/rest/v1/all',
useDefaultXhrHeader: false, // <= HERE
reader: {
type : 'json',
headers: {'Accept': 'application/json'},
totalProperty : 'total',
successProperty: 'success',
messageProperty: 'message'
}
} // <= and notice this change
});
可能不相关,但请注意您的压力不正确并隐藏了reader
选项已应用于商店本身而非代理(因此被忽略)这一事实。