只在跨域API请求中使用django-活塞

时间:2022-02-25 19:21:14

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):

我不能使用django-活塞对我的API进行POST/PUT/DELETE跨域请求,我已经使用这个脚本启用了CORS(基于这个脚本):

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 ?

在前端,我使用激活JSONP的主干。我没有任何错误,选项请求工作正常,然后什么都没有发生。我试图改变«访问控制允许-方法»,但它没有改变任何东西。任何想法?

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

1 个解决方案

#1


2  

JSONP is GET only:

JSONP是只有:

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.

不能跨域发布、放置或删除请求。通过使用向服务器发送动态JavaScript请求的

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.

然而,在处理跨域JavaScript时,推荐的方法之一是使用一个方法查询参数,您可以在服务器端代码中使用这个参数来确定应该如何处理特定的请求。

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.

在底层,它仍然是一个GET请求,但是您可以通过对API的微小修改来实现您的目标。

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

在确定请求类型时,不检查HTTP方法:

if request_method == "OPTIONS":    

Check the request parameter "method" instead:

改为检查请求参数“方法”:

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

JSONP Requests Must return JavaScript:

JSONP请求必须返回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.

需要注意的另一点是,JSONP请求必须在函数调用中返回包装(或填充)的JavaScript。由于请求是在后台由脚本标记发出的,因此服务器必须返回浏览器能够理解的内容。

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.

如果这对您没有意义,或者您需要更多信息,这里有一个关于JSONP和脚本标记远程工作原理的很好的解释。

#1


2  

JSONP is GET only:

JSONP是只有:

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.

不能跨域发布、放置或删除请求。通过使用向服务器发送动态JavaScript请求的

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.

然而,在处理跨域JavaScript时,推荐的方法之一是使用一个方法查询参数,您可以在服务器端代码中使用这个参数来确定应该如何处理特定的请求。

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.

在底层,它仍然是一个GET请求,但是您可以通过对API的微小修改来实现您的目标。

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

在确定请求类型时,不检查HTTP方法:

if request_method == "OPTIONS":    

Check the request parameter "method" instead:

改为检查请求参数“方法”:

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

JSONP Requests Must return JavaScript:

JSONP请求必须返回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.

需要注意的另一点是,JSONP请求必须在函数调用中返回包装(或填充)的JavaScript。由于请求是在后台由脚本标记发出的,因此服务器必须返回浏览器能够理解的内容。

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.

如果这对您没有意义,或者您需要更多信息,这里有一个关于JSONP和脚本标记远程工作原理的很好的解释。