Reader small image

You're reading from  CORS Essentials

Product typeBook
Published inMay 2017
Reading LevelIntermediate
Publisher
ISBN-139781784393779
Edition1st Edition
Languages
Right arrow
Author (1)
Rajesh Gunasundaram
Rajesh Gunasundaram
author image
Rajesh Gunasundaram

Rajesh Gunasundaram is a software architect, technical writer and blogger. He has over 15 years of experience in the IT industry, with more than 12 years using Microsoft .NET, 2 years of BizTalk Server and a year of iOS application development. Rajesh is a founder and editor of technical blogs programmerguide and ioscorner and you can find many of his technical writings on .Net and iOS. He is also the founder and developer of VideoLens, a platform that analyses videos uploaded in Facebook pages and YouTube channels. Rajesh has also written four other books for Packt publishing. Rajesh worked on client premises located at various countries such as UK, Belarus and Norway. He also has experience in developing mobile applications for iPhone and iPad. His technical strengths include Azure, Xamarin, ASP.NET MVC, Web API, WCF, .Net Framework / .Net Core, C#, Objective-C, Angular, Bot Framework, BizTalk, SQL Server, REST, SOA, Design Patterns and Software Architecture. Rajesh is an early adopter of Angular since AngularJS. He has developed Rich interfaces using Angular, Bootstrap, HTML5 and CSS3. He has good experience in translation of designer mock-ups and wireframes into an AngularJS front-end. Good at unit testing Angular applications with Karma. Expertise in handling RESTful services in Angular. Supporting various web products developed using AngularJS and Angular.
Read more about Rajesh Gunasundaram

Right arrow

CORS with Preflight


Preflight is a request the XHR object makes to ensure it's allowed to make another request.

Note

The CORS specification requires browsers to preflight requests that do the following:

  • Use any methods in the request other than GET, POST, or HEAD.

  • Include custom headers

  • Include content-type other than text/plain, application/x-www-form-urlencoded, or multipart/form-data

There's no preflight by default in CORS. Adding preflight makes your application more robust and handles errors better. However, it can also introduce complexities, which may be unnecessary when you are confident that the XHR request you need to make will be answered, and you only need to use GET, POST, or HEAD.

Triggering a preflight by setting a custom header

To trigger a preflight, set custom headers on the XHR request; the Access-Control-Allow-Methods header determines which HTTP methods can be used.

The preflight request

The following PHP code verifies for the OPTIONS request method during preflight. The server responds with the X-Requested-With header permitted:

if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
  // return only headers
  // The Preflight checks that the GET request method is supported
  if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD']) && $_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD'] == 'GET') {
    header('Access-Control-Allow-Origin: *');
    header('Access-Control-Allow-Headers: X-Requested-With');
  }
  exit;
}else{
  // error-handling code if the OPTIONS request method is unavailable
}

The preflight response

A successful server response returns the X-Requested-With method:

HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: X-Requested-With

CORS via jQuery

CORS via jQuery does not use preflight.

jQuery specifically avoids setting the custom header when making a CORS request. Therefore, it is better to use a separate preflight method when using jQuery for CORS.

Note

Here is the comment in the jQuery xhr.js library explaining why preflight is not used:

// X-Requested-With header

// For cross-domain requests, seeing as conditions for a preflight are

// akin to a jigsaw puzzle, we simply never set it to be sure.

// (it can always be set on a per-request basis or even using AJAXSetup)

// For same-domain requests, won't change header if already provided.

Known issues with CORS preflight

There are some common issues that developers face while implementing CORS preflight.

Preflight in Firefox

The CORS preflight request fails in Firefox when the OPTIONS request needs to be authenticated, causing the cross-origin request to fail. The request fails because authentication tokens are not sent with the preflight request. If the OPTIONS request fails, the preflight will result in 405 (method not allowed). Firefox ignores the request when the preflight fails.

Preflight in Chrome

Unlike Firefox, Chrome allows the request even if the option fails in preflight if the request and response headers are correct.

Preflight in Internet Explorer

Even when using withCredentials, IE doesn't send the auth tokens to preflight.

Tip

Should we avoid preflight entirely?

The best advice is to avoid using preflight entirely, unless you need to check whether requests are allowed.

Non-simple CORS request methods and headers require preflight

Any CORS request that uses a non-simple method or header requires preflight.

GET, POST, and HEAD are considered simple requests (and are case-sensitive). They do not require preflight.

The simple headers that do not require preflight are as follows:

  • Cache-control

  • Content-language

  • Content-type

  • Expires

  • Last-modified

  • Pragma

Any other method or header requires preflight.

Using the XMLHttpRequest level 2 event HandlersOriginally, XMLHttpRequest had only one event handler: onreadystatechange. XMLHttpRequest2 introduces new event handlers.

You may have noticed that when defining the XHR objects, we have used request.onload, which corresponds to the onload event when the request has successfully completed since we are interested in knowing whether the request has been successful.

Event handler

Description

Onreadystatechange

readyState property changes

onloadstart*

request starts

Onprogress

during loading and sending data.

onabort*

request has been aborted

Onerror

request has failed

Onload

request has successfully completed

ontimeout

specified timeout has expired before the request could complete

onloadend*

request has completed (success or failure)

* IE's XdomainRequest does not support handlers marked with asterisks

Checking for the withCredentials property

Check whether withCredentials property is available to determine whether the browser supports XMLHttpRequest level 2 event handlers. This could be handled as a preflight.

Previous PageNext Page
You have been reading a chapter from
CORS Essentials
Published in: May 2017Publisher: ISBN-13: 9781784393779
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
undefined
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $15.99/month. Cancel anytime

Author (1)

author image
Rajesh Gunasundaram

Rajesh Gunasundaram is a software architect, technical writer and blogger. He has over 15 years of experience in the IT industry, with more than 12 years using Microsoft .NET, 2 years of BizTalk Server and a year of iOS application development. Rajesh is a founder and editor of technical blogs programmerguide and ioscorner and you can find many of his technical writings on .Net and iOS. He is also the founder and developer of VideoLens, a platform that analyses videos uploaded in Facebook pages and YouTube channels. Rajesh has also written four other books for Packt publishing. Rajesh worked on client premises located at various countries such as UK, Belarus and Norway. He also has experience in developing mobile applications for iPhone and iPad. His technical strengths include Azure, Xamarin, ASP.NET MVC, Web API, WCF, .Net Framework / .Net Core, C#, Objective-C, Angular, Bot Framework, BizTalk, SQL Server, REST, SOA, Design Patterns and Software Architecture. Rajesh is an early adopter of Angular since AngularJS. He has developed Rich interfaces using Angular, Bootstrap, HTML5 and CSS3. He has good experience in translation of designer mock-ups and wireframes into an AngularJS front-end. Good at unit testing Angular applications with Karma. Expertise in handling RESTful services in Angular. Supporting various web products developed using AngularJS and Angular.
Read more about Rajesh Gunasundaram