What is the reason behind the browser permitting cross-origin POST requests but not PUT requests?

Let's consider a straightforward example of utilizing the XMLHttpRequest.

The following code snippet functions correctly (you can verify in the network tab or by navigating your browser to http://requestb.in/yckncpyc) despite displaying a warning in the console:

XMLHttpRequest cannot load . No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.

const method = "POST"
const req = new XMLHttpRequest()
req.open(method, 'http://requestb.in/yckncpyc')
req.send("foobar")
console.log("sent")
req.addEventListener('load', function() { console.log(req.status, req.response) })

I understand that part. What I find confusing is that switching the HTTP verb to PUT leads to a completely different outcome. The request made turns into an OPTIONS preflight request and returns:

XMLHttpRequest cannot load . Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.

const method = "PUT"
const req = new XMLHttpRequest()
req.open(method, 'http://requestb.in/yckncpyc')
req.send("foobar")
console.log("sent")
req.addEventListener('load', function() { console.log(req.status, req.response) })

Why does the behavior vary for these two scenarios? It appears to be a security measure, but one that may seem illogical since an attacker could easily use a POST instead of a PUT.

What is the rationale behind this differentiation?

  • I've tested this in Chrome 52 and Safari 9.1.2

Answer №1

GET, HEAD, and POST requests can be made cross-origin without any additional communication, with a few restrictions in place. However, the responses from these requests cannot be examined, only the requests are permitted.

Any other type of request requires a preflight request to inspect the headers from the target site to determine if the request is allowed.

This setup exists because historically, browsers have allowed GET, HEAD, and POST requests as part of standard HTML behavior. When CORS was introduced, these types of requests were continued to be allowed under the assumption that they posed no more vulnerability than before.

The browser evaluates the response headers to determine whether the requesting code on the cross-origin page should have access to the response content. For non-simple requests, an OPTIONS request is first sent to validate the CORS response headers. Only if these headers indicate permission will the XHR request be approved.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Guide on setting up a MEAN stack application to run on port 8080

I am brand new to the mean stack development environment. I'm attempting to configure my root domain name to display the app directory once I enter the command grunt, but the only way it currently works is at website.com:8080/!#/. How can I get it to ...

Instructions for running a script from a personalized NPM package

I have developed a unique NPM package that includes a script I want to run from another project. Here is an overview of my package: myScript.js console.log("The script has been executed!"); package.json { "name": "@myscope/my-script", "version": "0. ...

Encountering a bug: "Undefined property" issue when working with Web Sockets in React Native

I'm a beginner in React Native and Java Script development, and I'm facing an issue while trying to retrieve a JSON object and display it on the client side. I keep getting a "cannot read property of undefined" error when using websockets instead ...

"Step-by-Step Guide: Activating Tab Functionality in J

I'm facing an issue here - I've been attempting to log the event's key code and I keep getting key number (9). I believe my script isn't disabling event.keyCode properly, hence the key function remains active. What changes should I make ...

What could be causing the failure of the JSON parse for dynamic link parameters?

I am currently attempting to pass parameters to a dynamic page within an Amplify/NextJS application. This is still a work in progress. My objective is to utilize the passed parameters to generate a basic page based on 4 parameters included in the URL invo ...

Issue with displaying ng-repeat data in AngularJS tbody

I am experiencing an issue with using ng-repeat inside a tbody element. Here is the code snippet that is causing trouble: <tbody> <tr ng-repeat="group in groups"> <td>{{ group.name }}</td> </tr> </tbody> Wh ...

Creating a multi-step progress bar in Yii2 that showcases completed steps using jQuery

Is there a way to automatically transition from one state to another once the order status changes in Yii2? var i = 1; $('.progress .circle').removeClass().addClass('circle'); $('.progress .bar').removeClass().addClass(&a ...

Creating a dynamic HTML content using AJAX with the JQuery Mobile radio button widget

Looking for help with JQuery Mobiles as a newcomer. I've noticed that the radio button widget works fine when hard coded in an HTML file, but doesn't load properly when the same content is dynamically created using JavaScript through Ajax. Whene ...

Modify the image inside a div when hovering

How can I create a product card that displays thumbnails of images when hovered over, and changes the main image to the thumbnail image? My current challenge is getting this functionality to work individually for each card on an e-commerce site. Currently, ...

Event handler or callback function in Socialite.js

Exploring the capabilities of Socialite.js for the first time has been quite intriguing. This JavaScript plugin allows loading social media plugins after page load, adding an interesting dynamic to website interactivity. However, I am faced with the challe ...

implement a click event handler for GLmol (webGL)

Check out GLmol, a Molecular Viewer built on WebGL and Javascript by visiting You can see a demo of GLmol in action at I am interested in adding a click function to GLmol. For example, when I click on a ball, I would like to retrieve information about it ...

Showing a group of users in real-time as they connect using Socket IO

I've been working on setting up a system in Socket IO to create a list of individuals who join a 'party room'. The plan is to lock the party room once all players are present, and then display views to users. However, I've hit a roadblo ...

Creating a bold portion of a string

My task involves dynamically creating <p> elements within a div based on the contents of my codeArray, which can vary in size each time. Instead of hard-coding these elements, I have devised the following method: for(i=1;i<codeArray.length;i++) ...

Can you explain the functionality of `module.exports = mongoose model` in a NodeJs environment

Coming from a front-end React background, I am familiar with statements like import and exports. However, as I delve into learning Backend (NodeJs) with mongoDB, I find myself curious about the mechanics of import and export in this new environment. I hav ...

Issue with AWS SDK client-S3 upload: Chrome freezes after reaching 8 GB upload limit

Whenever I try to upload a 17 GB file from my browser, Chrome crashes after reaching 8 GB due to memory exhaustion. import { PutObjectCommandInput, S3Client } from '@aws-sdk/client-s3'; import { Progress, Upload } from "@aws-sdk/lib-storage& ...

Using Mysqli prepared statements in conjunction with AJAX POST to a PHP script

My query is regarding the efficiency of PHP Mysqli prepared statements. Based on my understanding from basic research, prepared statements offer enhanced security by using bound inputs and optimize the process by 'pre-packaging' SQL queries to so ...

Improving efficiency by saving and loading the form value using best practices

One of the challenges I'm facing is how to populate dropdown selections on a webpage without resorting to hard-coded procedures. The code snippet below illustrates the current setup: <td> <ui-select ng-model="user_profile.gender" require ...

Show the selected checkbox options upon clicking the submit button

Having trouble setting up a filter? I need to create a feature where checked values from checkboxes are displayed in a specific div after submitting. The display should include a 'Clear All' button and individual 'X' buttons to remove e ...

Ensuring the next tab is not accessible until all fields in the current tab are filled

I am working on a form with a series of questions displayed one at a time, like a slide show. I need help with preventing the user from moving to the next set of questions if there is an empty field in the current set. Below is the script I am using to nav ...

Generating a collection of items using a pre-existing array of items

Struggling to create an array of objects based on another array of objects. I attempted to use flatMap and then reduce, but encountered an issue when I tried to collect multiple statuses in one object. Below is what I have attempted and the desired result ...