File size: 7,861 Bytes
05a77ff
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
Corser
=======

[![Project Status: Active - The project has reached a stable, usable state and is being actively developed.](http://www.repostatus.org/badges/0.1.0/active.svg)](http://www.repostatus.org/#active)
[![Build Status](https://secure.travis-ci.org/agrueneberg/Corser.png)](http://travis-ci.org/agrueneberg/Corser)

A highly configurable, middleware compatible implementation of [CORS](http://www.w3.org/TR/cors/) for [Node.js](http://nodejs.org/).


Changelog
---------

### 2.0.1 (August 16, 2016)

* Add workaround for [Chrome 52 sending empty `Access-Control-Request-Headers` header](https://bugs.chromium.org/p/chromium/issues/detail?id=633729).

### 2.0.0 (March 22, 2014)

* Preflight requests are automatically closed. If there is a need for handling `OPTIONS` requests, check the `endPreflightRequests` option.
* The parameters of the callback function in dynamic origin checking are now `(err, matches)` instead of just `(matches)`.


Examples
--------

### How to use Corser as a middleware in Express

See `example/express/` for a working example.

    var express, corser, app;

    express = require("express");
    corser = require("corser");

    app = express();

    app.use(corser.create());

    app.get("/", function (req, res) {
        res.writeHead(200);
        res.end("Nice weather today, huh?");
    });

    app.listen(1337);

### How to use Corser as a middleware in Connect

See `example/connect/` for a working example.

    var connect, corser, app;

    connect = require("connect");
    corser = require("corser");

    app = connect();

    app.use(corser.create());

    app.use(function (req, res) {
        res.writeHead(200);
        res.end("Nice weather today, huh?");
    });

    app.listen(1337);

### How to use Corser with plain `http`

    var http, corser, corserRequestListener;

    http = require("http");
    corser = require("corser");

    // Create Corser request listener.
    corserRequestListener = corser.create();

    http.createServer(function (req, res) {
        // Route req and res through the request listener.
        corserRequestListener(req, res, function () {
            res.writeHead(200);
            res.end("Nice weather today, huh?");
        });
    }).listen(1337);


API
---

### Creating a Corser request listener

Creating a Corser request listener that generates the appropriate response headers to enable CORS is as simple as:

    corser.create()

This is the equivalent of setting a response header of `Access-Control-Allow-Origin: *`. If you want to restrict the origins, or allow more sophisticated request or response headers, you have to pass a configuration object to `corser.create`.

Corser will automatically end preflight requests for you. A preflight request is a special `OPTIONS` request that the browser sends under certain conditions to negotiate with the server what methods, request headers and response headers are allowed for a CORS request. If you need to use the `OPTIONS` method for other stuff, just set `endPreflightRequests` to `false` and terminate those requests yourself:

    var corserRequestListener;

    corserRequestListener = corser.create({
        endPreflightRequests: false
    });

    corserRequestListener(req, res, function () {
        if (req.method === "OPTIONS") {
            // End CORS preflight request.
            res.writeHead(204);
            res.end();
        } else {
            // Implement other HTTP methods.
        }
    });


#### Configuration Object

A configuration object with the following properties can be passed to `corser.create`.

##### `origins`

A case-sensitive whitelist of origins. Unless unbound, if the request comes from an origin that is not in this list, it will not be handled by CORS.

To allow for dynamic origin checking, a function `(origin, callback)` can be passed instead of an array. `origin` is the Origin header, `callback` is a function `(err, matches)`, where `matches` is a boolean flag that indicates whether the given Origin header matches or not.

Default: unbound, i.e. every origin is accepted.

##### `methods`

An uppercase whitelist of methods. If the request uses a method that is not in this list, it will not be handled by CORS.

Setting a value here will overwrite the list of default simple methods. To not lose them, concat the methods you want to add with `corser.simpleMethods`: `corser.simpleMethods.concat(["PUT", "DELETE"])`.

Default: simple methods (`GET`, `HEAD`, `POST`).

##### `requestHeaders`

A case-insensitive whitelist of request headers. If the request uses a request header that is not in this list, it will not be handled by CORS.

Setting a value here will overwrite the list of default simple request headers. To not lose them, concat the request headers you want to add with `corser.simpleRequestHeaders`: `corser.simpleRequestHeaders.concat(["Authorization"])`.

Default: simple request headers (`Accept`, `Accept-Language`, `Content-Language`, `Content-Type`, `Last-Event-ID`).

##### `responseHeaders`

A case-insensitive whitelist of response headers. Any response header that is not in this list will be filtered out by the user-agent (the browser).

Setting a value here will overwrite the list of default simple response headers. To not lose them, concat the response headers you want to add with `corser.simpleResponseHeaders`: `corser.simpleResponseHeaders.concat(["ETag"])`.

Default: simple response headers (`Cache-Control`, `Content-Language`, `Content-Type`, `Expires`, `Last-Modified`, `Pragma`).

##### `supportsCredentials`

A boolean that indicates if cookie credentials can be transferred as part of a CORS request. Currently, only a few HTML5 elements can benefit from this setting.

Default: `false`.

##### `maxAge`

An integer that indicates the maximum amount of time in seconds that a preflight request is kept in the client-side preflight result cache.

Default: not set.

##### `endPreflightRequests`

A boolean that indicates if CORS preflight requests should be automatically closed.

Default: `true`.


FAQ
---

### Ajax call returns `Origin X is not allowed by Access-Control-Allow-Origin`

Check if the `Origin` header of your request matches one of the origins provided in the `origins` property of the configuration object. If you didn't set any `origins` property, jump to the next question.


### Ajax call still returns `Origin X is not allowed by Access-Control-Allow-Origin`

Your request might use a non-simple method or one or more non-simple headers. According to the specification, the set of simple methods is `GET`, `HEAD`, and `POST`, and the set of simple request headers is `Accept`, `Accept-Language`, `Content-Language`, `Content-Type`, and `Last-Event-ID`. If your request uses **any** other method or header, you have to explicitly list them in the `methods` or `requestHeaders` property of the configuration object.


#### Example

You want to allow requests that use an `X-Requested-With` header. Pass the following configuration object to `corser.create`:

    corser.create({
        requestHeaders: corser.simpleRequestHeaders.concat(["X-Requested-With"])
    });


### Getting a response header returns `Refused to get unsafe header "X"`

Your browser blocks every non-simple response headers that was not explicitly allowed in the preflight request. The set of simple response headers is `Cache-Control`, `Content-Language`, `Content-Type`, `Expires`, `Last-Modified`, `Pragma`. If you want to access **any** other response header, you have to explicitly list them in the `responseHeaders` property of the configuration object.

#### Example

You want to allow clients to read the `ETag` header of a response. Pass the following configuration object to `corser.create`:

    corser.create({
        responseHeaders: corser.simpleResponseHeaders.concat(["ETag"])
    });