2

I'm not able to do POST/PUT/DELETE cross-domain request on my API using django-piston, I've CORS enabled using this script (based on this):

class CORSResource(Resource):
    """
    Piston Resource to enable CORS.
    """

    # headers sent in all responses
    cors_headers = [
        ('Access-Control-Allow-Origin', '*'),
        ('Access-Control-Allow-Headers', 'AUTHORIZATION'),
    ]

    # headers sent in pre-flight responses
    preflight_headers = cors_headers + [
        ('Access-Control-Allow-Methods', '*'),
        ('Access-Control-Allow-Credentials','true')
    ]
    def __init__(self, handler, authentication=None):
        super(CORSResource, self).__init__(handler, authentication)
        self.csrf_exempt = getattr(self.handler, 'csrf_exempt', True)

    def __call__(self, request, *args, **kwargs):

        request_method = request.method.upper()

        # intercept OPTIONS method requests
        if request_method == "OPTIONS":
            # preflight requests don't need a body, just headers
            resp = HttpResponse()

            # add headers to the empty response
            for hk, hv in self.preflight_headers:
                resp[hk] = hv

        else:
            # otherwise, behave as if we called the base Resource
            resp = super(CORSResource, self).__call__(request, *args, **kwargs)

            # slip in the headers after we get the response
            # from the handler
            for hk, hv in self.cors_headers:
                resp[hk] = hv

        return resp

    @property
    def __name__(self):
        return self.__class__.__name__

In the frontend I'm using Backbone with JSONP activated. I don't have any errors, the OPTIONS request works fine then nothing happens. I tried to change the « Access-Control-Allow-Methods » but it doesn't change anything. Any idea ?

Edit: Here is the request headers of an OPTIONS request:

OPTIONS /api/comments/ HTTP/1.1
Host: apitest.dev:8000
User-Agent: Mozilla/5.0 (X11; Linux i686; rv:12.0) Gecko/20100101 Firefox/12.0
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
DNT: 1
Connection: keep-alive
Origin: http://3l-oauth.dev:1338
Access-Control-Request-Method: POST
Access-Control-Request-Headers: authorization,content-type
Pragma: no-cache
Cache-Control: no-cache

and the response headers:

HTTP/1.0 200 OK
Date: Sat, 12 May 2012 09:22:56 GMT
Server: WSGIServer/0.1 Python/2.7.3
Access-Control-Allow-Methods: *
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: AUTHORIZATION
Content-Type: text/html; charset=utf-8
X-Frame-Options: SAMEORIGIN
djevg
  • 689
  • 1
  • 9
  • 15

1 Answers1

2

JSONP is GET only:

You cannot make POST, PUT, or DELETE requests cross-domain. Cross domain JavaScript is facilitated through the use of <script> tags that send requests to your server for dynamic JavaScript. script tags are GET requests only.

However, one of the recommended methods for adjusting to this limitation when dealing with cross-domain JavaScript is to use a method query parameter that you would use in your server-side code to determine how you should handle a specific request.

For instance, if the request was

POST /api/comments/

then you could do this:

/api/comments?method=POST

Under the hood, it's still a GET request, but you can achieve your goal with slight modifications to your API.

When determining the type of request, instead of checking the HTTP Method:

if request_method == "OPTIONS":    

Check the request parameter "method" instead:

 if request.GET["method"] == "OPTIONS":

JSONP Requests Must return JavaScript:

The other really important point to take note of is that your JSONP requests must all return JavaScript wrapped (or padded) in a function call. Since the requests are made under the hood by script tags that expect JavaScript, your server must return content that the browser understands.

If this doesn't make sense to you or you need more information, there is a great explanation here on how JSONP and script tag remoting works under the hood.

Community
  • 1
  • 1
jamesmortensen
  • 33,636
  • 11
  • 99
  • 120