Reputation: 826
I am having issues with making an ExtJS AJAX request to the Nodejs server between two different domains within our network and will appreciate any help. Response fails when attempting from both http and https from ExtJS client side but a Curl from my local via http returns 200 OK with proper data. We are working with content type application/json
.
ExtJS onReady function has enabled CORS:
Ext.onReady(function () {
Ext.Ajax.cors = true;
Ext.Ajax.useDefaultXhrHeader = false;
... (code removed)
})
A test from my ExtJS client side on a known working URL that will properly create the ExtJS datastore (brings back 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'
}
});
However, when attempting a request to our Nodejs server via
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'
}
});
returns the following in Chrome's console:
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.
Now, when attempted over https
:
Firefox shows:
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.
and the Request Header doesn't show "application/json", is this an issue?:
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
I then tried with Curl to see what the responses were to help debug
on http
gives a 200 OK response but Access-Control-Allow-Origin is undefined even when we are defining it as "*"
:
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* } ]
then when I attempt to Curl via 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
We have enabled CORS on our Nodejs server:
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');
I have attempted to be detailed in my thought process and I am willing to try new ways to determine how to understand and solve this.
* SOLUTION *
The issue is mixed content from the browser. Our client UI is on https (secure) whereas we were requesting http (unsecure) content from the nodejs server. We needed to allow for our nodejs server to run on https
We generated SSL certifications and implemented them onto our nodejs server.
Within the nodejs code, we enabled CORS with the CORS module and are running both http and https servers:
// 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);
});
Upvotes: 3
Views: 4782
Reputation: 25031
There seems to be issues with both CORS and HTTPS in your server... You should try this middleware for the CORS part, and make it work when accessing the page in raw HTTP first. As far as I know, you'll have to use different ports for HTTP and HTTPS. And you will also probably need to enable CORS credentials. As I said, I think you'd better make it work in HTTP first ;)
Then, on the Ext part, as already mentioned in comments, you should probably disable default headers (or you'll have to make all of them accepted by your server; see the first comment to this answer). But you need to do that on the proxy, because apparently it replaces the global setting in Ext.Ajax
.
So, something like this:
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
});
Probably unrelated, but note that your indendation was incorrect and hid the fact that the reader
option was applied to the store itself instead of the proxy (so it was ignored).
Upvotes: 4