Issue
I’m in the process of splitting into two different projects an Ember.js app and its Express REST API counterpart. I assumed that things would be cleaner this way.
Until then, my Express app was both serving REST endpoints and all static files like index.html
and app.js
. But now, ember-cli is in charge of serving the static files and the Express app handles authentication + REST.
The last issue I’m having is that I now have two different ports: ember-cli uses http://localhost:4200
and express uses http://localhost:3333
. When I get the session cookie from Express upon authentication, it’s never being sent on subsequent request because of same origin policy (see: How do I send an AJAX request on a different port with jQuery?).
Now if I understand correctly I have two solutions:
- Setup Express to support JSONP and make sure Ember uses it too
- Install a local Nginx or Apache and setup a proxy pass
The first solution is not ok because after deployment both apps will use the same domain/port. The second solution would probably work but it seems a bit ridiculous to ask developers to install a local web server to simply run an app.
I’m sure many of you have encountered that issue before. What would you suggest to make development easy?
Thanks!
Solution
Hmm. Seems like I found another solution:
Following instructions found there: http://discuss.emberjs.com/t/ember-data-and-cors/3690/2
export default DS.RESTAdapter.extend({
host: 'http://localhost:3333',
namespace: 'api',
ajax: function(url, method, hash) {
hash = hash || {}; // hash may be undefined
hash.crossDomain = true;
hash.xhrFields = { withCredentials: true };
return this._super(url, method, hash);
})
});
You will also need to add the following headers in the Express app:
// Add support for cross-origin resource sharing (localhost only)
app.all('*', function(req, res, next) {
if (app.get('env') === 'development') {
res.header('Access-Control-Allow-Origin', 'http://localhost:4200');
res.header('Access-Control-Allow-Headers', 'X-Requested-With, Content-Type');
res.header('Access-Control-Allow-Credentials', 'true');
res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE');
}
next();
});
That’s it! Last step is to make sure that Ember uses CORS only in the dev environment.
UPDATE
Ember-cli now has an integrated proxy feature that makes all the above obsolete.
From documentation: “Use –proxy flag to proxy all ajax requests to the given address. For example ember server --proxy http://127.0.0.1:8080
will proxy all your apps XHR to your server running at port 8080.”