关于我们

质量为本、客户为根、勇于拼搏、务实创新

< 返回新闻公共列表

ajax请求后端数据

发布时间:2021-06-07 09:57:45

  AJAX提供了一种无需刷新页面即可将GET或POST请求发送到Django视图并接收返回的数据的方法。现代JavaScript包括fetch  API,它提供了发送AJAX请求的纯JavaScript方法。

  让我们看一下如何导入GET和POST请求,在视图和模板之间传递JSON数据。

GET请求

  • 生成GET请求

  通过提供视图的URL和相应的headers参数来获取GET请求。请求运行后,视图将返回请求的数据,并将响应转换为JSON,以便在其他任务中使用。

      headers:{
          'Accept': 'application/json',
          'X-Requested-With': 'XMLHttpRequest', //Necessary to work with request.is_ajax()
      },
  })
  .then(response => {
      return response.json() //Convert response to JSON  })
  .then(data => {
      //Perform actions with the response data from the view  })
Python
Copy

URL

  提取使用URL作为第一个参数。根据Django项目的URLconf和视图的组织方式,URL可能包含关键字参数或查询字符串,用于在视图中选择请求的数据。

Headers

  设置AJAX请求标头参数。尝试以JSON格式从视图中返回数据。因此,请将Accept参数设置为application/json。在视图中,您可以确认请求是否为AJAX请求。此视图可以确认请求是否为AJAX,包括设置为XMLHttpRequest的X-Requested-With标头。

  Get不直接返回数据。返回响应,响应返回请求的响应。要从响应中获取数据。必须多次使用then处理程序以使用链响应。第一个。then接收已处理的响应并将其转换为JSON。第二次。then是第一个。允许访问then返回的数据,使其可用,然后处理数据,如更新页面操作。

在视图中处理GET请求

需要能够处理Fetch调用中的AJAX请求的视图。可以通过多种方法完成此任务,但最简单的方法之一是使用接受请求并返回请求数据所在的JsonResponse的基于函数的视图。

# views.pyfrom django.http import JsonResponsedef ajax_get_view(request): # May include more arguments depending on URL parameters
    # Get data from the database - Ex. Model.object.get(...)
    data = {
            'my_data':data_to_display    }
    return JsonResponse(data)
Python
Copy

  如果通过包含附加参数的URL访问视图,则这些附加参数也将与请求一起包含在功能参数列表中。根据相应的URL参数或查询字符串(如果使用)从数据库中检索数据。要发送回页面的数据必须使用JsonResponse。调用前,必须从django.http获取JsonResponse。

  此视图返回JsonResponse,它序列化数据词典,并通过链接发送回要处理的页面。现在可以使用JavaScript用GET请求中的数据更新页面的一部分。

POST请求

  • 通过提取发出POST请求

带GET的POST请求比GET请求需要更多的参数。

fetch(URL, {
      method: 'POST',
      credentials: 'same-origin',
      headers:{
          'Accept': 'application/json',
          'X-Requested-With': 'XMLHttpRequest', //Necessary to work with request.is_ajax()
          'X-CSRFToken': csrftoken,
  },
      body: JSON.stringify({'post_data':'Data to post'}) //JavaScript object of data to POST  })
  .then(response => {
        return response.json() //Convert response to JSON  })
  .then(data => {
  //Perform actions with the response data from the view  })
Python
Copy

Method

默认为发出GET请求。我们必须通过添加方法“ POST”来明确地告诉它发出POST请求。

Credentials

我们需要指定如何在请求中发送凭据。凭证可能很棘手,特别是如果项目的前端和后端分别托管。如果AJAX请求是通过与后端其他位置相同的模板提供的,我们可以使用默认值“ same-origin”。这意味着,如果所请求的URL与提取调用来自同一站点,则将在请求中发送用户凭据。如果前端和后端不在某个位置,则需要使用不同的凭据设置,并且需要考虑跨域资源共享(CORS)。

Headers

“ Accept”和“ X-Requested-With”标头与GET请求的标头相同,但是现在必须包括一个附加的“ X-CSRFToken”标头。

向Django发出POST请求时,我们需要包含csrf令牌以防止跨站点请求伪造攻击。Django文档提供了我们需要添加的确切JavaScript代码,以从csrftoken cookie中获取令牌。

function getCookie(name) {
      let cookieValue = null;
      if (document.cookie && document.cookie !== '') {
          const cookies = document.cookie.split(';');
          for (let i = 0; i < cookies.length; i++) {
              const 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;
  }
  const csrftoken = getCookie('csrftoken');
Python
Copy

现在我们有了csrftoken,我们将其添加到标头中作为“X-CSRFToken”:csrftoken。

BODY

POST请求的目标是将数据发送到视图并更新数据库。 这意味着我们还需要在fetch调用中包含数据。 假设我们要发送JSON数据,我们添加主体:JSON.stringify(data)其中data是我们要发送的数据的JavaScript对象。 除了JSON数据(包括文件和来自表单的数据)外,其他数据也可以在正文中发送。 有关如何包含其他类型的数据的更多信息,请参见MDN文档。

我们从POST请求中获得的响应将像GET请求一样使用链式承诺进行处理。

在视图中处理POST请求

接受POST请求的视图将从请求中获取数据,对其执行一些操作,然后返回响应。

# views.py
from django.http import JsonResponse
import json

def ajax_post_view(request):
    data_from_post = json.load(request)['post_data'] #Get data from POST request
    #Do something with the data from the POST request
    #If sending data back to the view, create the data dictionary
    data = {
        'my_data':data_to_display,
    }
    return JsonResponse(data)

我们需要从AJAX请求中提取数据才能使用它。数据以JSON格式发送,因此我们需要使用json.load(request)将其加载到视图中。这需要从Python标准库中导入json模块。结果是我们通过提取发送的数据的字典。现在,我们可以通过其键访问数据。

一旦获得了请求中的数据,我们就可以执行用户希望启动AJAX请求的操作。这可能是创建模型的新实例或更新现有实例。

与GET请求一样,可以使用JsonResponse和带有数据的字典将数据发送回页面。这可以是新的或更新的模型对象,也可以是成功消息。

确保请求是AJAX

在大多数情况下,都会发出AJAX请求,因为我们只希望更新页面的一部分,并且需要获取新数据来进行更新。在页面上下文之外,JsonResponse返回的数据本身很少使用。但是,如果我们没有正确设置视图,则可以在AJAX请求之外访问数据,并且不会像我们期望的那样将其呈现给用户。

为了防止这种情况的发生,我们可以使用request.is_ajax()方法在视图中添加检查以确保该请求是AJAX请求。

# views.py
from django.http import JsonResponse

def ajax_view(request):
    if request.is_ajax():
        data = {
                'my_data':data_to_display
        }
        return JsonResponse(data)

这使用“ X-Requested-With”标头来确定请求是否由AJAX发起。 如果尝试通过直接在浏览器中键入URL来访问此视图,则会收到错误消息。可以向视图中添加其他逻辑(例如重定向),以防止用户尝试在没有AJAX请求的情况下访问视图时看到错误。

Django 3.1及更高版本

在即将发布的Django3.1版本(2020年8月)中,request.is_ajax()将被弃用。 这意味着如果我们要检查AJAX请求,则必须自己重新创建功能。 幸运的是,Django开发人员确切地告诉我们我们需要做什么。 我们必须自己从request.is_ajax()方法重新创建逻辑,该逻辑只有1行代码:

request.headers.get('x-requested-with') == 'XMLHttpRequest'

现在,我们可以编辑视图以包括此检查:

def ajax_view(request):
  if request.headers.get('x-requested-with') == 'XMLHttpRequest':
    # Get requested data and create data dictionary
    return JsonResponse(data))

一些重要注意事项

  获取是发送AJAX请求的便捷方法,但并非所有浏览器(即所有版本的InternetExplorer)都支持提取。如果需要IE支持,请查看jQuery或XMLHttpRequest以提交AJAX请求。

  AJAX请求应限制在Django项目的一小部分。如果直接在多个模板中使用以获取大量数据,建议您使用Django  Rest  Framework创建API。

  摘要

  在Django项目中,使用AJAX请求可以更改页面的某些部分,而无需重新加载整个页面。提取API使您能够以最少的JavaScript轻松地添加此功能。正确谨慎地使用可以加快页面速度,并为用户提供更多的交互体验。




/template/Home/Qiggg/PC/Static