I've lately been trying to build a Dart client that communicates with my Dart docker server. If I run this url (localhost:8080/id/6192449487634432) on any browser I get back a JSON that I've set up, however, if a use
HttpRequest
.getString ("http://localhost:8080/id/6192449487634432")
.then (print);
on the Dart client, I get this weird error
XMLHttpRequest cannot load http://localhost:8080/id/6192449487634432. No 'Access-Control-Allow-Origin'
header is present on the requested resource. Origin 'http://localhost:8081' is therefore not allowed access.
I've searched and some workarounds have been to build a PHP proxy (no thanks). I am new to web development in general and I definitely don't know what a proxy is or how to build one. Is there a clean solution I could use? I have a Redstone server and and AngularDart client.
Thanks a lot!
This happens when your client app is served from a different server than your docker server. This is a browser issue, not specific to Dart. Luckily, the solution is easy.
Be sure to send CORS headers from your server, on every request. The easiest way to solve this is to add the following header:
Access-Control-Allow-Origin: *
I don't know the specifics of Redstone, but be sure to set the header key Access-Control-Allow-Origin
and value *
on GET
, HEAD
, and POST
methods. Yes, you need to set this header on HEAD
requests because sometimes the browser does a HEAD request to check if CORS is enabled.
Learn more about CORS at http://enable-cors.org/
As mentioned above setting the Access-Control-Allow-Origin
header allows HTTP requests from the browser to go to other URLs than the origin the client was loaded from. Another option is to serve the Dart client from the same server as you are accessing.
Depending on your environment and whether you are using Dartium or a JavaScript browser
If you are using Dart on App Engine Managed VMs we have built-in support for this, so that requests for the client files are proxied to pub serve
during development and served from the output from pub build
when deployed. See A Client-Server Example.
If you are running a plain Dart server right now there is no canned solution for switching between pub serve
and pub build
. You can run pub build
and serve the files out of the web/build
directory.
We are working on making the solution provided for Dart on App Engine Managed VMs more generally available.
Particularly to redstone, you can solve the problem as follows. Add to your server-side code this snippet
// if not yet there
import 'package:redstone/server.dart' as app;
@app.Interceptor(r'/.*')
interceptor() {
app.chain.next(() {
app.response = app.response.change(headers: {
"Access-Control-Allow-Origin": "*"
});
});
}
you can read more on interceptors in the redstone wiki