jQuery $.ajax(), $.post sending “OPTIONS” as REQUE

2018-12-31 17:35发布

Having trouble with what I thought was a relatively simple jQuery plugin...

The plugin should fetch data from a php script via ajax to add options to a <select>. The ajax request is pretty generic:

$.ajax({
  url: o.url,
  type: 'post',
  contentType: "application/x-www-form-urlencoded",
  data: '{"method":"getStates", "program":"EXPLORE"}',
  success: function (data, status) {
    console.log("Success!!");
    console.log(data);
    console.log(status);
  },
  error: function (xhr, desc, err) {
    console.log(xhr);
    console.log("Desc: " + desc + "\nErr:" + err);
  }
});

This seems to work fine in Safari. In Firefox 3.5, the REQUEST_TYPE on the server is always 'OPTIONS', and the $_POST data does not appear. Apache logs the request as type 'OPTIONS':

::1 - - [08/Jul/2009:11:43:27 -0500] "OPTIONS sitecodes.php HTTP/1.1" 200 46

Why would this ajax call work in Safari, but not Firefox, and how do I fix it for Firefox?

Response Headers
Date: Wed, 08 Jul 2009 21:22:17 GMT
Server:Apache/2.0.59 (Unix) PHP/5.2.6 DAV/2
X-Powered-By: PHP/5.2.6
Content-Length  46
Keep-Alive  timeout=15, max=100
Connection  Keep-Alive
Content-Type    text/html

Request Headers
Host    orderform:8888
User-Agent  Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1) Gecko/20090624 Firefox/3.5
Accept  text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language en-us,en;q=0.5
Accept-Encoding gzip,deflate
Accept-Charset  ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive  300
Connection  keep-alive
Origin  http://ux.inetu.act.org
Access-Control-Request-Method   POST
Access-Control-Request-Headers  x-requested-with

Here is a picture of the Firebug output:

23条回答
伤终究还是伤i
2楼-- · 2018-12-31 18:08

I've fixed this issue using an entirely-Apache based solution. In my vhost / htaccess I put the following block:

# enable cross domain access control
Header always set Access-Control-Allow-Origin "*"
Header always set Access-Control-Allow-Methods "POST, GET, OPTIONS"

# force apache to return 200 without executing my scripts
RewriteEngine On
RewriteCond %{REQUEST_METHOD} OPTIONS
RewriteRule .* / [R=200,L]

You may not need the latter part, depending on what happens when Apache executes your target script. Credit goes to the friendly ServerFault folk for the latter part.

查看更多
无色无味的生活
3楼-- · 2018-12-31 18:08

Try to add the following:

dataType: "json",
ContentType: "application/json",
data: JSON.stringify({"method":"getStates", "program":"EXPLORE"}),  
查看更多
伤终究还是伤i
4楼-- · 2018-12-31 18:09

Culprit is preflight request using OPTIONS method

For HTTP request methods that can cause side-effects on user data (in particular, for HTTP methods other than GET, or for POST usage with certain MIME types), the specification mandates that browsers "preflight" the request, soliciting supported methods from the server with an HTTP OPTIONS request method, and then, upon "approval" from the server, sending the actual request with the actual HTTP request method.

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

I resolved the problem by adding following lines in Nginx conf.

    location / {
               if ($request_method = OPTIONS ) {
                   add_header Access-Control-Allow-Origin  "*";
                   add_header Access-Control-Allow-Methods "POST, GET, PUT, UPDATE, DELETE, OPTIONS";
                   add_header Access-Control-Allow-Headers "Authorization";
                   add_header Access-Control-Allow-Credentials  "true";
                   add_header Content-Length 0;
                   add_header Content-Type text/plain;
                   return 200;
               }
    location ~ ^/(xxxx)$ {
                if ($request_method = OPTIONS) {
                    rewrite ^(.*)$ / last;
                }
    }
查看更多
荒废的爱情
5楼-- · 2018-12-31 18:09

Can you try this without

contentType:application/x-www-form-urlencoded

查看更多
无色无味的生活
6楼-- · 2018-12-31 18:12

I had same problem with sending requests to google maps, and solution is quite simple with jQuery 1.5 - for dataType use dataType: "jsonp"

查看更多
登录 后发表回答