By Corey Ogburn


2014-02-14 15:20:26 8 Comments

I am working on an internal web application at work. In IE10 the requests work fine, but in Chrome all the AJAX requests (which there are many) are sent using OPTIONS instead of whatever defined method I give it. Technically my requests are "cross domain." The site is served on localhost:6120 and the service I'm making AJAX requests to is on 57124. This closed jquery bug defines the issue, but not a real fix.

What can I do to use the proper http method in ajax requests?

Edit:

This is in the document load of every page:

jQuery.support.cors = true;

And every AJAX is built similarly:

var url = 'http://localhost:57124/My/Rest/Call';
$.ajax({
    url: url,
    dataType: "json",
    data: json,
    async: true,
    cache: false,
    timeout: 30000,
    headers: { "x-li-format": "json", "X-UserName": userName },
    success: function (data) {
        // my success stuff
    },
    error: function (request, status, error) {
        // my error stuff
    },
    type: "POST"
});

9 comments

@Andrew Tatomyr 2018-05-26 17:50:04

I've encountered a very similar issue. I spent almost half a day to understand why everything works correctly in Firefox and fails in Chrome. In my case it was because of duplicated (or maybe mistyped) fields in my request header.

@Evhz 2017-11-12 15:38:19

Consider using axios

axios.get( url,
{ headers: {"Content-Type": "application/json"} } ).then( res => {

  if(res.data.error) {

  } else { 
    doAnything( res.data )
  }

}).catch(function (error) {
   doAnythingError(error)
});

I had this issue using fetch and axios worked perfectly.

@Skylin R 2017-12-01 10:37:25

Axios also use first OPTIONS

@Noorullah 2017-05-08 14:42:35

"preflighted" requests first send an HTTP request by the OPTIONS method to the resource on the other domain, in order to determine whether the actual request is safe to send. Cross-site requests

https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS

@Badacadabra 2017-05-08 15:16:18

Could you add a bit more information? Your answer looks like a comment. :)

@Mahesh 2016-10-19 13:17:12

As answered by @Dark Falcon, I simply dealt with it.

In my case, I am using node.js server, and creating a session if it does not exist. Since the OPTIONS method does not have the session details in it, it ended up creating a new session for every POST method request.

So in my app routine to create-session-if-not-exist, I just added a check to see if method is OPTIONS, and if so, just skip session creating part:

    app.use(function(req, res, next) {
        if (req.method !== "OPTIONS") {
            if (req.session && req.session.id) {
                 // Session exists
                 next();
            }else{
                 // Create session
                 next();
          }
        } else {
           // If request method is OPTIONS, just skip this part and move to the next method.
           next(); 
        }
    }

@gbonesso 2016-06-16 11:32:37

In my case I'm calling an API hosted by AWS (API Gateway). The error happened when I tried to call the API from a domain other than the API own domain. Since I'm the API owner I enabled CORS for the test environment, as described in the Amazon Documentation.

In production this error will not happen, since the request and the api will be in the same domain.

I hope it helps!

@Aidin 2016-02-12 20:54:39

If it is possible pass the params through regular GET/POST with a different name and let your server side code handles it.

I had a similar issue with my own proxy to bypass CORS and I got the same error of POST->OPTION in Chrome. It was the Authorization header in my case ("x-li-format" and "X-UserName" here in your case.) I ended up passing it in a dummy format (e.g. AuthorizatinJack in GET) and I changed the code for my proxy to turn that into a header when making the call to the destination. Here it is in PHP:

if (isset($_GET['AuthorizationJack'])) {
    $request_headers[] = "Authorization: Basic ".$_GET['AuthorizationJack'];
}

@Dropout 2014-10-07 12:58:55

Based on the fact that the request isn't sent on the default port 80/443 this Ajax call is automatically considered a cross-origin resource (CORS) request, which in other words means that the request automatically issues an OPTIONS request which checks for CORS headers on the server's/servlet's side.

This happens even if you set

crossOrigin: false;

or even if you ommit it.

The reason is simply that localhost != localhost:57124. Try sending it only to localhost without the port - it will fail, because the requested target won't be reachable, however notice that if the domain names are equal the request is sent without the OPTIONS request before POST.

@jgitter 2014-02-14 15:31:01

I agree with Kevin B, the bug report says it all. It sounds like you are trying to make cross-domain ajax calls. If you're not familiar with the same origin policy you can start here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Same_origin_policy_for_JavaScript.

If this is not intended to be a cross-domain ajax call, try making your target url relative and see if the problem goes away. If you're really desperate look into the JSONP, but beware, mayhem lurks. There really isn't much more we can do to help you.

@Corey Ogburn 2014-02-14 15:32:53

Our system structure is something I can't change. Using a different port is a requirement of our architecture. I get same origin policy but thought that the CORS we implemented was enough. Apparently not.

@jgitter 2014-02-14 15:37:22

If your server returns JSON responses, you can look into JSONP method, just use it responsibly.

@Ray Nicholus 2014-02-14 15:37:47

JSON has nothing to do with JSONP

@jgitter 2014-02-14 15:40:22

I don't really care to argue with you, but JSONP uses script tags to pull in data from another domain and then sends the result to a callback function. It's a lot harder if the result isn't json.

@Ray Nicholus 2014-02-14 15:45:05

No, it isn't a lot harder. In fact the response should not be valid JSON in any case. Instead, the server should return something like this: callbackfunc(somedata). As you can see, this is not valid JSON. And, somedata can be a string, or a number, or whatever you want it to be.

@jgitter 2014-02-14 15:46:03

Fair enough. But seriously, not arguing.

@Garet Claborn 2014-06-17 19:50:02

@RayNicholus JSONP most definitely has something to do with JSON. While poorly named it is "JSON with padding" where the callback is the padding. While you can use it for other purposes than JSON, the point and intend use of JSONP is to get cross-origin JSON working. en.wikipedia.org/wiki/JSONP "conventionally, it is a JavaScript fragment that invokes a function call on some JSON-formatted data."

@Ray Nicholus 2014-06-17 20:13:28

JSONP has just as much to do with JSON as it does with HTML, or XML, or <insert data format here>. As you said, JSONP can operate on any data. That was really my point, that and the server does not return JSON, instead, it returns a function invocation.

@ErwinGO 2015-07-06 04:43:42

I'm using Postman and there the request methods are sent correctly (eg. 'PUT', 'DELETE', etc). But when i try to do it from my code it always send them with the request method OPTIONS. I have no idea how Postman is able to do it.

@Dark Falcon 2014-02-14 15:23:47

Chrome is preflighting the request to look for CORS headers. If the request is acceptable, it will then send the real request. If you're doing this cross-domain, you will simply have to deal with it or else find a way to make the request non-cross-domain. This is why the jQuery bug was closed as won't-fix. This is by design.

Unlike simple requests (discussed above), "preflighted" requests first send an HTTP request by the OPTIONS method to the resource on the other domain, in order to determine whether the actual request is safe to send. Cross-site requests are preflighted like this since they may have implications to user data. In particular, a request is preflighted if:

  • It uses methods other than GET, HEAD or POST. Also, if POST is used to send request data with a Content-Type other than application/x-www-form-urlencoded, multipart/form-data, or text/plain, e.g. if the POST request sends an XML payload to the server using application/xml or text/xml, then the request is preflighted.
  • It sets custom headers in the request (e.g. the request uses a header such as X-PINGOTHER)

@Corey Ogburn 2014-02-14 15:29:31

Custom headers. That's probably what's setting off the preflight OPTIONS calls.

Related Questions

Sponsored Content

21 Answered Questions

[SOLVED] jQuery Get Selected Option From Dropdown

  • 2012-05-18 20:11:54
  • William Kinaan
  • 1094004 View
  • 884 Score
  • 21 Answer
  • Tags:   javascript jquery html

15 Answered Questions

[SOLVED] Ajax request returns 200 OK, but an error event is fired instead of success

13 Answered Questions

20 Answered Questions

[SOLVED] jQuery get specific option tag text

12 Answered Questions

[SOLVED] How to send a PUT/DELETE request in jQuery?

11 Answered Questions

[SOLVED] jQuery Ajax POST example with PHP

12 Answered Questions

[SOLVED] JavaScript/jQuery to download file via POST with JSON data

17 Answered Questions

[SOLVED] How do I send a cross-domain POST request via JavaScript?

10 Answered Questions

[SOLVED] How to send FormData objects with Ajax-requests in jQuery?

23 Answered Questions

[SOLVED] jQuery $.ajax(), $.post sending "OPTIONS" as REQUEST_METHOD in Firefox

Sponsored Content