The Access-Control-Allow-Origin header is a server-side response header that is used in cross-origin resource sharing (CORS) to indicate whether or not a browser should be allowed to request a resource from a different origin.
An origin is the combination of a scheme (such as http or https), a hostname, and a port. For example, the origin https://example.com is different than https://subdomain.example.com. When a browser makes a request to a different origin, it sends an Origin request header to the server indicating the origin of the request. The server can then respond with an Access-Control-Allow-Origin header, which indicates whether or not the browser should be allowed to access the resource.
Here's an example of a simple CORS request where the server responds with Access-Control-Allow-Origin: https://example.com.
// Request from browser
GET /api/data HTTP/1.1
Origin: https://example.com
// Response from server
HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://example.com
However, if a request is a non-simple request, such as a request that uses a method other than GET, HEAD, or POST (like PUT or DELETE), or includes custom headers, then the browser will first send a preflight request (an HTTP OPTIONS request) to the server to check if the actual request is safe to send. The server will then return an Access-Control-Allow-Origin header in its response to the preflight request to indicate whether or not the browser should proceed with the actual request.
Here's an example of a non-simple CORS request where the server responds with Access-Control-Allow-Origin: https://example.com and Access-Control-Allow-Methods: PUT
// Preflight request from browser
OPTIONS /api/data HTTP/1.1
Origin: https://example.com
Access-Control-Request-Method: PUT
// Response from server
HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Methods: PUT
// Actual request from browser
PUT /api/data HTTP/1.1
Origin: https://example.com
// Preflight request from browser
OPTIONS /api/data HTTP/1.1
Origin: https://example.com
Access-Control-Request-Method: PUT
// Response from server
HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Methods: PUT
// Actual request from browser
PUT /api/data HTTP/1.1
Origin: https://example.com
It is important to note that the server must also return the Access-Control-Allow-Methods header in its preflight response to indicate which HTTP verbs are allowed, and in case of custom headers, the `Access-Control-Allow-Head
The Access-Control-Allow-Origin header is used in a response to indicate which origin(s) are allowed to access the resources of the server. The value of the header can be set to a specific origin, or to the wildcard * which allows any origin to access the resources.
Here's an example of how the Access-Control-Allow-Origin header can be set in a Node.js server using the cors package:
const express = require('express');
const cors = require('cors');
const app = express();
app.use(cors({
origin: 'http://example.com'
}));
app.get('/', (req, res) => {
res.json({ message: 'Hello from the server!' });
});
app.listen(3000, () => {
console.log('Server running on http://localhost:3000');
});
In this example, the server is set up to only allow requests from the origin http://example.com. If a request is made from a different origin, the browser will receive a Access-Control-Allow-Origin header with a value of null, and the request will be blocked by the browser.
A origin is the combination of protocol, domain and port from where the request is coming from.
A non-simple request is defined as a request that uses an HTTP verb other than GET or POST, or that sets a custom header. These types of requests require preflight checks, which are done with an HTTP OPTIONS request.
Here's an example of how a non-simple request can be made using the fetch API:
fetch('http://example.com/api/resource', {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer YOUR_TOKEN'
},
body: JSON.stringify({ key: 'value' })
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error(error));
In this example, the request uses the PUT HTTP verb and sets a custom Content-Type and Authorization header. Before the browser sends this request, it will first send a preflight request (OPTIONS) to the server to check if the server will accept these kind of request.
It's important to note that the server must also include the Access-Control-Allow-Methods header to indicate which HTTP verbs are allowed for non
simple requests, such as PUT or DELETE. This header can include one or more of the following:
Access-Control-Allow-Methods: GET
Access-Control-Allow-Methods: GET, POST
Access-Control-Allow-Methods: * (allows all HTTP verbs)
Here's an example of a server-side script that echoes back the headers sent by the client and sets the Access-Control-Allow-Origin and Access-Control-Allow-Methods headers:
<?php
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Methods: GET, POST, PUT, DELETE");
header("Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept");
echo json_encode(getallheaders());
?>
On the client-side, you would make an HTTP request and handle the response as you normally would, but you must set the Access-Control-Request-Method header to indicate the desired HTTP verb for the non-simple request.
For example, to make a PUT request:
var xhr = new XMLHttpRequest();
xhr.open("PUT", "http://yourserver.com/api/resource");
xhr.setRequestHeader("Access-Control-Request-Method", "PUT");
xhr.send();
Keep in mind that browser's security policies are designed to prevent web pages from making requests to a different domain than the one that served the web page. This is known as the "same-origin policy" and it's designed to prevent some types of cross-site forgery attacks.
Tags:
HTTP