GVKun编程网logo

ajax – 如何在django中的preflighted CORS POST请求中处理CSRF?(django使用ajax)

5

在本文中,我们将详细介绍ajax–如何在django中的preflightedCORSPOST请求中处理CSRF?的各个方面,并为您提供关于django使用ajax的相关解答,同时,我们也将为您带来关

在本文中,我们将详细介绍ajax – 如何在django中的preflighted CORS POST请求中处理CSRF?的各个方面,并为您提供关于django使用ajax的相关解答,同时,我们也将为您带来关于.NET Web API CORS PreFlight请求、30_Django中关于使用ajax发送请求中`csrf_token`的问题和解决、ajax post请求+django后台处理、ajax 把get请求改为post请求(django)的有用知识。

本文目录一览:

ajax – 如何在django中的preflighted CORS POST请求中处理CSRF?(django使用ajax)

ajax – 如何在django中的preflighted CORS POST请求中处理CSRF?(django使用ajax)

我试图通过 AJAX从abc.com发出POST请求到xyz.com(这是一个Django应用程序)的URL.
我通过向xyz.com上的URL发出GET请求来获取CSRF令牌,但是当在preflighted请求中向xyz.com发出OPTIONS请求时,令牌会更改.

有没有办法在预检请求中获得OPTIONS请求的响应?

注意:

我遵循以下来源的指示:

> https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest
> https://developer.mozilla.org/en/docs/HTTP/Access_control_CORS
> http://www.html5rocks.com/en/tutorials/cors/

Django CSRF保护将允许OPTIONS请求,因此第一阶段没有问题:

https://docs.djangoproject.com/en/dev/ref/contrib/csrf/#how-it-works

如果我理解正确,那么您希望允许下一个请求(例如跨域POST).为了使其工作并超越Django的CSRF保护,请求必须发送CSRF令牌(在POST数据或AJAX的头文件中)和匹配的CSRF cookie.

现在,跨域限制使得abc.com无法为xyz.com设置或读取cookie,无论是来自javascript还是来自服务器端响应.因此,这种方法是不可能的.

相反,您必须将@csrf_exempt应用于视图.这将允许任何网站发布到它.因此,您需要为视图构建一些其他保护.当然,您可以自行检查保护的安全性.请记住,“Referer”和“Origin”标题可以很容易地用像curl这样基本的东西伪造.

.NET Web API CORS PreFlight请求

.NET Web API CORS PreFlight请求

我有麻烦使PUT和DELETE CORS请求到其他域上的Web API.

我已经通过http://www.asp.net/web-api/overview/security/enabling-cross-origin-requests-in-web-api#create-webapi-project教程编写了API.

GET和POST请求工作正常,但DELETE和PUT不.我收到这个消息:

Failed to load resource: the server responded with a status of 405 (Method Not Allowed)
Failed to load resource: No 'Access-Control-Allow-Origin' header is present on the requested resource.

当我添加代码到WebConfig建议在CORS support for PUT and DELETE with ASP.NET Web API,我只得到第一个错误.

有人可以帮我吗

解决方法

您可以添加一个处理程序来处理这种类型的请求.

创建一个派生自“DelegatingHandler”的类:

public class PreflightRequestsHandler : DelegatingHandler
{
    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request,CancellationToken cancellationToken)
    {
        if (request.Headers.Contains("Origin") && request.Method.Method.Equals("OPTIONS"))
        {
            var response = new HttpResponseMessage { StatusCode = HttpStatusCode.OK };
            // Define and add values to variables: origins,headers,methods (can be global)               
            response.Headers.Add("Access-Control-Allow-Origin",origins);
            response.Headers.Add("Access-Control-Allow-Headers",headers);
            response.Headers.Add("Access-Control-Allow-Methods",methods);
            var tsc = new taskcompletionsource<HttpResponseMessage>();
            tsc.SetResult(response);
            return tsc.Task;
        }
        return base.SendAsync(request,cancellationToken);
    }

}

后来在WebApiconfig.cs中的Register方法添加:

public static void Register(HttpConfiguration config)
{
    // Define and add values to variables: origins,methods (can be global) 
    // Enable global CORS
    config.EnableCors(new EnableCorsAttribute(origins,methods));

    // Add handler to deal with preflight requests,this is the important part
    config.MessageHandlers.Add(new PreflightRequestsHandler()); // Defined above
    .
    .
    .
}

30_Django中关于使用ajax发送请求中`csrf_token`的问题和解决

30_Django中关于使用ajax发送请求中`csrf_token`的问题和解决

Django中关于csrf_token的问题和解决

[TOC]

在需要发送POST请求的html文件中引入下面的js代码, 我为其命名为get_csrf_token.js, 我下面的几个处理都需要使用到这一js代码文件

$(() => {
    function getCookie(name) {
        var cookieValue = null;
        if (document.cookie && document.cookie !== '''') {
            var cookies = document.cookie.split('';'');
            for (var i = 0; i < cookies.length; i++) {
                var cookie = cookies[i].trim();
                // Does this cookie string begin with the name we want?
                if (cookie.substring(0, name.length + 1) === (name + ''='')) {
                    cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                    break;
                }
            }
        }
        return cookieValue;
    }

    function csrfSafeMethod(method) {
        // these HTTP methods do not require CSRF protection
        return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
    }
    $.ajaxSetup({
        beforeSend: function(xhr, settings) {
            if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
                xhr.setRequestHeader("X-CSRFToken", getCookie(''csrftoken''));
            }
        }
    });

});

1. 在form表单中加上{% csrf_token %}

2. 使用装饰器的方法,可以不用在form表单中添加上{% csrf_token %}

(当然了这种方法与上面在每个form表单中添加上csrf_token 没有什么区别,都是只针对单个的)

from django.utils.decorators import method_decorator
from django.views.decorators.csrf import ensure_csrf_cookie

class LoginView(View):
    """
    登录
    url: /user/login/
    """
    @method_decorator(ensure_csrf_cookie)   # 获取csrf_token值
    def get(self, request):
        """
        响应登录get请求
        返回登录页面
        """
        return render(request, ''user/login.html'')

    def post(self, request):
        """
        登录功能
        :param request:
        :return:
        """
        pass

3. 使用中间件,为每个请求都获取到token (使用这个方法,所有的表单都不需要在form标签中添加上{% csrf_token %} 了)

  1. 定义一个中间件
# 文件路径,如为: utils/my_middleware.py
from django.utils.deprecation import MiddlewareMixin
from django.middleware.csrf import get_token

class GetCsrfTokenMiddleware(MiddlewareMixin):
    def process_request(self, request):
        """执行视图之前被调用,在每个请求上被调用"""
        get_token(request)
  1. 在settings.py 中找到 MIDDLEWARE, 注册中间件
# 中间件
MIDDLEWARE = [
    ...
    ''utils.my_middleware.GetCsrfTokenMiddleware''
    # ''中间件文件路径.中间件文件名.定义的中间件类''
]

ajax post请求+django后台处理

ajax post请求+django后台处理

选择行:
$(document).ready(function() {
    var table = $(''#table_id_example'').DataTable();
    //定义一个表格示例变量
    $(''#table_id_example tbody'').on( ''click'', ''tr'', function () {
      //选中表格,tbody标签。在每一行上的tr行上绑定一个点击事件click.
        if ( $(this).hasClass(''selected'') ) {
          //如果鼠标点击这个行,那么在这个tr标签中搜索selected属性,如果tr行有selected属性那么。
            $(this).removeClass(''selected'');
            //如果这个行有selected属性,那么将此属性删除。
        }
        else {
            table.$(''tr.selected'').removeClass(''selected'');
            //如果被选中的行本身没有selected属性。那么删除整个表格中带有selected属性的行,将selected属性删除。
            $(this).addClass(''selected'');
            //然后给当前鼠标点击的行tr标签天津一个标签属性selected。
        }
    } );

//删除行

$(''#del'').click(function () {
      if (table.rows(''.selected'').data().length) {
        //查找这个表格的行中具有selected属性的行。获取改行的数据的length长度。如果不为0.那么
        $("#modaldel").modal()
        //只需对id=modaldel的模态框执行显示操作。
      } else {
        alert(''请选择项目'');//如果他没有数据说明没有选中提示没有选中
      }
    });

  $(''#delete'').click(function () {
    //上面ok后给这个模态框中的确认按钮属性id=delete的添加一个动作。
    //table.row(''.selected'').remove().draw(false); 
    //多这个表格带有selected属性的行进行删除。并且draw刷新表格。

      //通过ajax将其传值实现删除
        var data ={username:''wangyunlong'',Ip:''8.8.8.8''};
        $.ajax({
                          url : "/deltable/", 
                          //data : {''students'':JSON.stringify(list)},
                          data : JSON.stringify(data),
                          type:"post",
                          contentType:''application/json'',//传到后台的数据必须是json格式
                          dataType : "json", //后台返回的数据必须是json格式
                          success : function(data) {  
                            console.log(''ajax删除数据请求:'',data.status);
                            },
                          error : function(data) {  
                            console.log(''ajax删除数据请求:Error'');
                          },
                   }); 

  
})

url 配置:    path(''deltable/'',views.deltable,name=''deltable''),

def deltable(request):
    import json
    content={
    ''status'':''Success'',
    ''mesg'':''服务器返回的数据'',
    }
    if request.method ==''POST'':
        data=request.body #数据在body里面
        json_data=json.loads(data) #解析json格式的数据
        print("所有数据:",json_data)
        username=json_data.get("username")#获取key为username的值
        Ip = json_data.get("Ip") #获取key为ip的值
        print(''前端POST请求到达上传值为:%s,%s''%(username,Ip));
    return HttpResponse(json.dumps(content)) #将返回的字典转换为json格式

ajax 把get请求改为post请求(django)

ajax 把get请求改为post请求(django)

以下代码可以正常运行。(index.js文件)

setInterval(function () {
       console.log( "kaishi" + timeText())
  $.ajax(
    {
        type:'get',  // 不指定默认就是get,都是小写
        success:function (response) {
        console.log(response)
            $('#picture').attr('src', response.imgPath) 	 //修改<img>标签的src值
            $('#number').text(response.result)		//修改id="number"标签的内容
            }
        }
  )
},10000)	//10s

​ 我希望与页面加载的同时,此代码就开始执行,并且每隔10s执行一次。

​ 为了和首次打开页面区分,我把ajax请求的类型改为post,其他不变

type:'post'

会报如下错误(ajax发送的请求为我的首页):

Forbidden (CSRF token missing.): /index/

解决办法:

  • 第一步 index.html : 引用query.cookie.js插件(建议将此文件下载到本地,不然只能在联网下使用,可以确定此方法可行后再下载)
<script src="https://cdn.staticfile.org/jquery-cookie/1.4.1/jquery.cookie.min.js"></script>
  • 第二步 index.js : 在success函数前添加请求头 headers: {“X-CSrftoken”: $.cookie(‘csrftoken’)}
setInterval(function () {
      console.log( "kaishi" + timeText())
 $.ajax(
   {
       type:'post',  // 不指定默认就是get,都是小写
       //以下是添加的代码
       headers: {"X-CSrftoken": $.cookie('csrftoken')},
       //以上是添加的代码
       success:function (response) {
       console.log(response)
           $('#picture').attr('src', response.imgPath) 	 //修改<img>标签的src值
           $('#number').text(response.result)		//修改id="number"标签的内容
           }
       }
 )
},10000)	//10s

过程中遇到的报错:

  • 第一种 : 在浏览器查看控制台报错:

    在这里插入图片描述


    原因 : cookie的问题,需要在index.html文件中引用query.cookie.js插件
<script src="https://cdn.staticfile.org/jquery-cookie/1.4.1/jquery.cookie.min.js"></script>
  • 第二种 : 终端报错:
Forbidden (CSRF token missing.): /index/

原因:没有加入这句代码

headers: {"X-CSrftoken": $.cookie('csrftoken')},

今天的关于ajax – 如何在django中的preflighted CORS POST请求中处理CSRF?django使用ajax的分享已经结束,谢谢您的关注,如果想了解更多关于.NET Web API CORS PreFlight请求、30_Django中关于使用ajax发送请求中`csrf_token`的问题和解决、ajax post请求+django后台处理、ajax 把get请求改为post请求(django)的相关知识,请在本站进行查询。

本文标签: