JQuery & Django Ajax 踩过的坑

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Allocator/article/details/77942162

JQuery & Django Ajax 踩过的坑

现在做一个数据可视化的项目,由于核心的机器学习代码使用python写的,数据可视化用的是D3.js 现在要给老大们展示这个结果,于是简单搭建了一个web application. 个人比较偏向于用Node.js 去完成但是出于程序员对技术的挚爱以及之前一直没有用过python搭建web application. 于是尝试了一下,但是没想到其中有这么多的坑,于是总结了一下自己在开发过程中遇到的一些坑以及解决方法,希望能够帮助后续的读者能够及时解决这些问题,减少在这些问题上的时间损耗

403 forbidden

遇到这种情况从服务端可以看到提示 CSRF cookie not set 的提示。 针对这种情况主流的是两种解决方式:1.直接disable csrf 验证的功能,因为本身CSRF为了避免跨站点的脚本攻击而引入的机制,但是如果是非生产环境,只是自己试验的话完全可以考虑disable这个功能;2. 正常使用这个功能,在CSRF work的情况下保证Ajax 成功。个人是比较推荐第二种方法。

Disable CSRF

首先需要在在settings.py里面的MIDDLEWARE_CLASSES 中加入
django.middleware.csrf.CsrfResponseMiddleware
对于低版本的Django(1.2左右没有考证过) 添加这一段之后就可以解决问题,但是对于高版本的Django 这一步还没有完全解决问题,还需要在处理http请求的python代码里面如下的代码:

from django.views.decorators.csrf import csrf_exempt

...

@csrf_exempt
def my_post(request):
    return HttpResponse('test')

如此才能够通过disable CSRF 的方式让程序正常运行起来。

Enable CSRF

在实现正常的enable CSRF 的情况下完成ajax处理之前,第一步需要了解Django中的引入的CSRF到底是什么,它的运行机制又是什么。关于CSRF参考我的另外一篇blog. CSRF(cross-site request forgery) 跨站点请求伪造。如果要保证CSRF机制正常运转的,实现Ajax功能需要完成如下的几点:第一,请求中携带csrf_token . 在get 请求中不需要携带token 就能够正常访问,而在post 请求中必须携带token 不然会报错。如果是表格的提交(虽然不在Ajax请求的范围内,但是一般为POST请求,所以需要携带token)需要在表格中添加{% csrf_token %} 即可例子如下:

<form method="POST" action="/postinf">
    {% csrf_token %}
    <input type="text" name="t_csrf"/>
    <input type="submit" value="Submit"/>
</form>

如果没有添加token 一般出现错误是CSRF cookie not set
然后是ajax 请求下的token 问题,最简单一个方案,在执行Ajax call 之前添加如下代码:

$.ajaxSetup({
    data: {csrfmiddlewaretoken: '{{ csrf_token }}' },
});

例子如下:

$(document).ready(function(){
    $.ajaxSetup({
        data: {csrfmiddlewaretoken: '{{ csrf_token }}' },
    });
    function ajaxhandler(data,status){
        alert(data);
    }
    $("#bu").click(function(){
        $.post("/ajax_post",{"id":1},ajaxhandler);
    });
});

最终能够正常实现ajax获取服务端数据.

JQuery Ajax请求URL以及Django中路由配置问题

Django中路由配置依然依赖于字符模式匹配,一个最简单的例子,配置Django主页一般在urls.py 中添加如下的配置:

urlpatterns = [
    url(r'^$',views.main_page),
]

如果使用JQuery的ajax 功能获取服务端内容那么在JavaScript脚本以及Django的urls.py 中需要特别注意url匹配问题。如下例子,假设脚本发送一个POST 请求到服务端获取数据,发送请求URL为http://127.0.0.1:8000/postinf 脚本中写法如下:

$.post('/postinf',{"id":1},postHandler);

而在于Django的服务端程序urls.py 中应该是如下的配置:

urlpatterns = [
    url(r'^$',views.main_page),
    url(r'^postinf',views.do_post),
]

比较坑的就是url中的斜线。脚本中需要添加而服务端配置路由的地方却不需要添加,不然出现404.

总结

目前项目中使用到Django的功能还比较简单,后面遇到问题我会及时更新文章。

猜你喜欢

转载自blog.csdn.net/Allocator/article/details/77942162