How to Set Custom CORS Headers
Validated on 23 May 2022 • Last edited on 16 Dec 2025
Functions are blocks of code that run on demand without the need to manage any infrastructure. Develop on your local machine, test your code from the command line (using doctl), then deploy to a production namespace or App Platform — no servers required.
By default, DigitalOcean Functions adds permissive CORS headers to every preflight OPTIONS request sent to a web action. You can customize your function’s CORS headers to limit which origins can call your API, constrain allowed methods and headers, and enable authenticated requests.
Default CORS Behavior
If the incoming request includes the Access-Control-Request-Headers header, Functions echoes it back as Access-Control-Allow-Headers. Otherwise, it returns the default values shown in the following response:
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: OPTIONS, GET, DELETE, POST, PUT, HEAD, PATCH
Access-Control-Allow-Headers: Authorization, Origin, X-Requested-With, Content-Type, Accept, User-Agent
Enable Custom OPTIONS Responses
To enable manual handling of OPTIONS requests, set the web flag and the web-custom-options: true annotation in your project.yml file:
packages:
- name: sample
functions:
- name: cors
runtime: 'nodejs:18'
web: true
annotations:
web-custom-options: trueRead Project Configuration YAML File for more information about project.yml.
Next, update your function to return custom CORS headers.
Example Handler (Node.js)
The following function returns custom CORS headers for preflight requests and a minimal body for other methods. Adapt the logic for other runtimes as needed:
function main(event) {
// Handle CORS preflight requests: browsers send OPTIONS
// before cross-origin calls to check allowed methods/headers.
if (event.method === 'options') {
return {
statusCode: 200,
headers: {
// Limit which origin can access this endpoint.
'Access-Control-Allow-Origin': 'https://example.com',
// Only allow specific HTTP methods for cross-origin calls.
'Access-Control-Allow-Methods': 'OPTIONS, GET',
// Only expose required request headers.
'Access-Control-Allow-Headers': 'Authorization, Content-Type'
}
}
}
return {
// Respond to non-OPTIONS requests with a simple body.
body: 'ok',
// Include a matching Allow-Origin on actual responses
// so browsers permit the frontend to read this response.
headers: { 'Access-Control-Allow-Origin': 'https://example.com' }
}
}
exports.main = mainUpdate https://example.com to your own domain in the example above.
Keep the following in mind when customizing your CORS headers:
- Return only the methods you intend to support in
Access-Control-Allow-Methods. - Use a specific origin instead of
*when you need credentialed requests. - Include only required headers in
Access-Control-Allow-Headersto reduce attack surface.
See How to Create Functions for details on packaging and deploying functions.