origin resource sharing (CORS) post request working

I have a machine on my local lan (machineA) that has two web servers. The first is the in-built one in XBMC (on port 8080) and displays our library. The second server is a CherryPy python script (port 8081) that I am using to trigger a file conversion on demand. The file conversion is triggered by a AJAX POST request from the page served from the XBMC server.

  • Goto http://machineA:8080 which displays library
  • Library is displayed
  • User clicks on 'convert' link which issues the following command -
  • jQuery Ajax Request

    $.post('http://machineA:8081', {file_url: 'asfd'}, function(d){console.log(d)})
    
  • The browser issues a HTTP OPTIONS request with the following headers;
  • Request Header - OPTIONS

    Host: machineA:8081
    User-Agent: ... Firefox/4.01
    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: 115
    Connection: keep-alive
    Origin: http://machineA:8080
    Access-Control-Request-Method: POST
    Access-Control-Request-Headers: x-requested-with
    
  • The server responds with the following;
  • Response Header - OPTIONS (STATUS = 200 OK)

    Content-Length: 0
    Access-Control-Allow-Headers: *
    Access-Control-Max-Age: 1728000
    Server: CherryPy/3.2.0
    Date: Thu, 21 Apr 2011 22:40:29 GMT
    Access-Control-Allow-Origin: *
    Access-Control-Allow-Methods: POST, GET, OPTIONS
    Content-Type: text/html;charset=ISO-8859-1
    
  • The conversation then stops. The browser, should in theory, issue a POST request as the server responded with the correct (?) CORS headers (Access-Control-Allow-Origin: *)
  • For troubleshooting, I have also issued the same $.post command from http://jquery.com. This is where I am stumped, from jquery.com, the post request works, a OPTIONS request is sent following by a POST. The headers from this transaction are below;

    Request Header - OPTIONS

    Host: machineA:8081
    User-Agent: ... Firefox/4.01
    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: 115
    Connection: keep-alive
    Origin: http://jquery.com
    Access-Control-Request-Method: POST
    

    Response Header - OPTIONS (STATUS = 200 OK)

    Content-Length: 0
    Access-Control-Allow-Headers: *
    Access-Control-Max-Age: 1728000
    Server: CherryPy/3.2.0
    Date: Thu, 21 Apr 2011 22:37:59 GMT
    Access-Control-Allow-Origin: *
    Access-Control-Allow-Methods: POST, GET, OPTIONS
    Content-Type: text/html;charset=ISO-8859-1
    

    Request Header - POST

    Host: machineA:8081
    User-Agent: ... Firefox/4.01
    Accept: */*
    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: 115
    Connection: keep-alive
    Content-Type: application/x-www-form-urlencoded; charset=UTF-8
    Referer: http://jquery.com/
    Content-Length: 12
    Origin: http://jquery.com
    Pragma: no-cache
    Cache-Control: no-cache
    

    Response Header - POST (STATUS = 200 OK)

    Content-Length: 32
    Access-Control-Allow-Headers: *
    Access-Control-Max-Age: 1728000
    Server: CherryPy/3.2.0
    Date: Thu, 21 Apr 2011 22:37:59 GMT
    Access-Control-Allow-Origin: *
    Access-Control-Allow-Methods: POST, GET, OPTIONS
    Content-Type: application/json
    

    I can't work out why the same request would work from one site, but not the other. I am hoping someone might be able to point out what I am missing. Thanks for your help!


    I finally stumbled upon this link "A CORS POST request works from plain javascript, but why not with jQuery?" that notes that jQuery 1.5.1 adds the

     Access-Control-Request-Headers: x-requested-with
    

    header to all CORS requests. jQuery 1.5.2 does not do this. Also, according to the same question, setting a server response header of

    Access-Control-Allow-Headers: *
    

    does not allow the response to continue. You need to ensure the response header specifically includes the required headers. ie:

    Access-Control-Allow-Headers: x-requested-with 
    

    REQUEST:

     $.ajax({
                url: "http://localhost:8079/students/add/",
                type: "POST",
                crossDomain: true,
                data: JSON.stringify(somejson),
                dataType: "json",
                success: function (response) {
                    var resp = JSON.parse(response)
                    alert(resp.status);
                },
                error: function (xhr, status) {
                    alert("error");
                }
            });
    

    RESPONSE:

    response = HttpResponse(json.dumps('{"status" : "success"}'))
    response.__setitem__("Content-type", "application/json")
    response.__setitem__("Access-Control-Allow-Origin", "*")
    
    return response
    

    Well I struggled with this issue for a couple of weeks.

    The easiest, most compliant and non hacky way to do this is to probably use a provider JavaScript API which does not make browser based calls and can handle Cross Origin requests.

    Eg Facebook JavaScript API and Google JS API.

    In case your API provider is not current and does not support Cross Origin Resource Origin '*' header in its response and does not have a JS api (Yes I am talking about you Yahoo ),you are struck with one of three options-

  • Using jsonp in your requests which adds a callback function to your URL where you can handle your response. Caveat this will change the request URL so your API server must be equipped to handle the ?callback= at the end of the URL.

  • Send the request to your API server which is controller by you and is either in the same domain as the client or has Cross Origin Resource Sharing enabled from where you can proxy the request to the 3rd party API server.

  • Probably most useful in cases where you are making OAuth requests and need to handle user interaction Haha! window.open('url',"newwindowname",'_blank', 'toolbar=0,location=0,menubar=0')

  • 链接地址: http://www.djcxy.com/p/7324.html

    上一篇: 如何加载和使用/动态调用JavaScript

    下一篇: 原始资源共享(CORS)发布请求工作