【问题标题】:Only GET working in cross domain API request with django-piston仅 GET 使用 django-piston 在跨域 API 请求中工作
【发布时间】:2012-05-20 16:56:50
【问题描述】:

我无法使用 django-piston 在我的 API 上执行 POST/PUT/DELETE 跨域请求,我已使用此脚本启用了 CORS(基于 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__

在前端,我使用的是激活 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

【问题讨论】:

    标签: javascript ajax django cors django-piston


    【解决方案1】:

    JSONP 仅是 GET:

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

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

    例如,如果请求是

    POST /api/comments/
    

    那么你可以这样做:

    /api/comments?method=POST
    

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

    判断请求类型时,不检查HTTP Method:

    if request_method == "OPTIONS":    
    

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

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

    JSONP 请求必须返回 JavaScript:

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

    如果这对您没有意义或您需要更多信息,请联系great explanation here on how JSONP and script tag remoting works under the hood

    【讨论】:

      猜你喜欢
      • 2013-02-24
      • 2015-01-17
      • 2014-02-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-31
      • 2016-08-14
      • 2017-09-12
      相关资源
      最近更新 更多