How to add CORS to the Dart server

AppVesto LLC
4 min readMar 1, 2021

--

Good day, my name is Andrew. I am the Flutter Developer. A few months ago, I started to write servers for a Flutter using Dart. My choice fell on Dart because it’s the language in which flutter itself is written, which means that they don’t have much difference in syntax. This has quite a few advantages. You can create one model on the server from the most straightforward example and then use that same model in the application. It’s pretty much speeds up the writing. However, the problem is that the language is not that popular, and there are not many ready-made packages. This is probably the main drawback. However, if you have a good experience with flutter, you can try your hand at writing Dart servers. You won’t have any difficulties.

Now, from the introductory part to the main. When I started working with flutter web, I encountered that the application could not send requests to the server. After a short recheck, I found out that the flutter web requires CORS to work with the Netwrix. Let’s try to understand what CORS is and why it is needed.

Cross-Origin Resource Sharing (CORS) is an HTTP header-based mechanism that allows the server to specify any other origin (domain, scheme, or port) than its own. The browser should allow the download of resources. CORS also relies on a mechanism by which browsers make a pre-request to the server hosting the cross-original resource to verify that it has allowed the actual request. In this pre-request, the browser sends headers indicating the HTTP method and the headers used in the actual request. This is the essential thing we’re interested in at this point. CORS also provides some interesting features, but we’re not so interested in that right now.

After I encountered this problem, the first solution I found was to use the “Cross Anyway” service. To work with it, we need to specify the URL of the service when calling our server. It will look like this:

https://cors-anywhere.herokuapp.com/ + URL of our server.

The URL to the proxy is taken from the path, checked, and proxied. The protocol part of the proxy URI is optional and defaults to “HTTP.” If port 443 is specified, the protocol defaults to “HTTP.” This has the advantage that we do not have to do anything ourselves. However, its main disadvantage is the limitation of 50 requests per hour, by default. Plus, it is not very reliable to transfer all requests through a third-party service. In this regard, this option was not suitable for me, and in general, it is quite problematic. After much research, I have not succeeded in this and could not find anything. Because of this, I decided to implement a mechanism that adds the necessary headers.

And so, for the beginning, it is necessary to create a map, which will have all the required headers.

const corsHeaders = {‘Access-Control-Allow-Origin’: ‘*’,‘Access-Control-Allow-Methods’: ‘GET, POST, DELETE, OPTIONS’,‘Access-Control-Allow-Headers’: ‘*’,};

Let’s walk through each of them individually:
Access-Control-Allow-Origin — parameter, which is responsible for the source of access to the resource. The “*” means that access can come from anyone. For example, if we specify this:


‘Access-Control-Allow-Headers’: ‘https://foo.example',

That means it will only get access at the URL https://foo.example.
Access-Control-Allow-Methods is the parameter that is responsible for which method the server will apply.
The Access-Control-Allow-Headers response header is used in response to the pre-flight request, which includes Access-Control-Request-Headers to indicate which HTTP headers can be used during the actual request.

Okay, next we need to return our header sheet when the request is of type “OPTIONS.” To do this, let’s create middleware.

const corsHeaders = {‘Access-Control-Allow-Origin’: ‘*’,‘Access-Control-Allow-Methods’: ‘GET, POST, DELETE, OPTIONS’,‘Access-Control-Allow-Headers’: ‘*’,};shelf.Response _options(shelf.Request request) =>(request.method == ‘OPTIONS’) ? shelf.Response.ok(null, headers: corsHeaders) : null;shelf.Response _cors(shelf.Response response) => response.change(headers: corsHeaders);final _fixCORS = shelf.createMiddleware(requestHandler: _options, responseHandler: _cors);

Once created, it must be added for the handler.

final handler = const shelf.Pipeline().addMiddleware(_fixCORS).addMiddleware(shelf.logRequests()).addHandler(_echoRequest);var server = await io.serve(handler,_hostname,8800,);

After that, the cors should work. The solution itself is not that complicated, but the mechanics and principles of work are interesting. I hope you found this article useful, in it I wanted to share my experience, which may be helpful to you.

--

--

AppVesto LLC

We are a team of rock-star developers, which provides fully-flexible and powerful products 💥.