2

我无法使用 django-piston 在我的 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__

在前端,我使用激活了 JSONP 的 Backbone。我没有任何错误,OPTIONS 请求工作正常,然后什么也没有发生。我试图更改« Access-Control-Allow-Methods »,但它没有改变任何东西。任何想法 ?

编辑: 这是 OPTIONS 请求的请求标头:

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

和响应头:

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
4

1 回答 1

2

JSONP 仅是 GET:

您不能跨域发出 POST、PUT 或 DELETE 请求。<script>通过使用向您的服务器发送动态 JavaScript 请求的标签,可以促进跨域JavaScript。脚本标签只是 GET 请求。

但是,在处理跨域 JavaScript 时调整此限制的推荐方法之一是使用方法查询参数,您将在服务器端代码中使用该参数来确定应如何处理特定请求。

例如,如果请求是

POST /api/comments/

那么你可以这样做:

/api/comments?method=POST

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

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

if request_method == "OPTIONS":    

改为检查请求参数“method”:

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

JSONP 请求必须返回 JavaScript:

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

如果这对您没有意义,或者您需要更多信息,这里有一个很好的解释,说明 JSONP 和脚本标签远程处理如何在幕后工作

于 2012-05-12T09:29:56.220 回答