How Does the Access-Control-Allow-Origin Header Work

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.

Mudasir Abbas Turi

Hi, this is Mudasir Abbas Turi. I am a Full-stack PHP and JavaScript developer with extensive experience in building and maintaining web applications. Skilled in both front-end and back-end development, with a strong background in PHP and JavaScript. Proficient in modern web development frameworks such as Laravel and ReactJS. Proven ability to develop and implement highly interactive user interfaces, and to integrate with various APIs and databases. Strong problem-solving skills and ability to work independently and as part of a team. Passionate about staying up-to-date with the latest technologies and industry trends.

Post a Comment

Previous Post Next Post