Django @csrf_exempt 装饰器不工作

Django @csrf_exempt decorator not working

我在 linode 服务器上使用 DJango 1.8,并且有以下视图:

import json

from django.http import HttpResponse
from django.shortcuts import render
from django.views.decorators.csrf import csrf_exempt

def home_view(request):
        r = { 'response': 'OK', 'data': None }
        return HttpResponse(json.dumps(r), content_type = "application/json")

@csrf_exempt
def ping(request):
        r = { 'response': 'OK', 'data': 'ping' }
        return HttpResponse(json.dumps(r), content_type = "application/json")

我的网址如下所示:

urlpatterns = [
    url(r'^django/admin/', include(admin.site.urls)),
    url(r'^django/$', home_view),
    url(r'^django/ping/$', ping),
    url(r'^django/echo/$', echo),
]

如果我访问我的 linode 网站 http://mylinodesite/django/ping/

我得到:

{"data": "ping", "response": "OK"}

太棒了。如果我使用 jquery 并执行

$.get("http://mylinodesite/django/ping/")

我明白了

No 'Access-Control-Allow-Origin' header is present on the requested resource.

根据我的理解,@csrf_exempt 应该摆脱 CSRF header 的东西。给出了什么?

这与 CSRF 没有任何关系,CSRF 仅用于 POST 操作,由 Django 强制执行。

您正在进行跨域 GET 操作。浏览器默认禁止这样做,因为所谓的同源策略:一个 JS 脚本只能向它加载的同一个域发出请求。所以,你被浏览器本身阻止了。

要启用对命名域的请求,您可以使用名为 CORS, which uses a header in the request. See the jQuery Ajax documentation.

的东西

丹尼尔,事实证明你只对了一部分。它是 CORS,但不能固定在 jQuery 端。这是我的 Django 视图代码,可以执行我想要的操作。请注意,它添加了 Access-Control-Allow-Origin header 以仅允许来自所有 (*) 的请求 GET

这也只是演示如何在一个文件中完成所有这些操作。如果需要,可以创建中间件来为所有请求执行此操作,但这很有效,并且是一个很好的例子,说明如何在一个地方完成所有操作,这样你就可以看到发生了什么,here is the full gist of the entire view file:

def ping(request):
        r = { 'response': 'OK', 'data': 'ping' }
        response = HttpResponse("['ok']", content_type="application/json")
        response['Access-Control-Allow-Origin'] = '*'
        response['Access-Control-Allow-Methods'] = 'GET'

        return response