Robin
Robin

Reputation: 1261

Options method not allowed, CORS to Google Drive

I've created a script for a google drive which posts to this document.

I invoke it with

var request = $.ajax({
            url: "https://script.google.com/macros/s/AKfycbypnRet5l6gUmoGE8oZV2_6da7fImNU12ejHCHCdOambH7UM2CP/exec",
            data: serializedData,
            type: "POST",
            timeout: 10000,
            async: true,
            crossDomain: true
        });

which works from this jsFiddle.

However, when I implement the exact same code into my local project, it doesn't work. I receive

XMLHttpRequest cannot load https://script.google.com/macros/s/AKfycbypnRet5l6gUmoGE8oZV2_6da7fImNU12ejHCHCdOambH7UM2CP/exec. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access. The response had HTTP status code 405.

405 is "Method not allowed", and when I inspect the network traffic I see that for my local request the method is

Request Method:OPTIONS

However, for the one in jsFiddle it is post as expected. I've done some research, and it seems as if options is a preflight request when doing cross origin, and I can't make it use post directly.

The non-working OPTIONS request has has the following headers that aren't in the working Fiddle's request:

access-control-request-headers:accept, content-type
access-control-request-method:POST

If I post the same request to my server (instead of to Google), I see it contains the request header Content-Type:application/json; charset=UTF-8.

How does jsFiddle get through, when the options method is not allowed? Can I somehow make it skip options and go straight to post?

Upvotes: 4

Views: 3741

Answers (1)

apsillers
apsillers

Reputation: 115930

Preflight OPTIONS requests occur when the request is non-simple, either caused by a non-simple header or a non-simple HTTP method.

The access-control-request-headers: accept, content-type header means that you are attempting to send non-simple headers. Accept is always simple, but Content-Type is only simple when it has the value application/x-www-form-urlencoded, multipart/form-data, or text/plain. It must be the case that your code (for whatever reason) is trying to use a non-simple value for Content-Type, and Google is not providing an Access-Control-Allow-Headers response header to allow it.

Instead, you must specify a simple value for Content-Type. You can do this by adding an explicit contentType: "application/x-www-form-urlencoded; charset=UTF-8" property to your $.ajax options object.

Upvotes: 4

Related Questions