Django中利用AJAX与Fetch API实现局部页面更新的完整指南
本文详解如何在Django项目中利用现代JavaScript的Fetch API实现AJAX请求,以达成无需刷新页面的局部数据更新。内容涵盖GET与POST请求的具体参数配置、JsonResponse的使用、CSRF令牌处理,以及Django 3.1版本中request.is_ajax()弃用后的替代方案,帮助开发者提升Web应用的交互体验与性能。
在使用Django构建Web服务时,常规操作下只要用户触发任何导致页面变化的行为,无论该变化仅涉及页面的微小部分,服务器都会将完整的HTML模板发送给浏览器。然而,若我们仅需更新页面的特定区域,则无需重新渲染整个页面,此时引入AJAX技术便成为更优选择。
使用AJAX获取Django后端数据插图
AJAX技术允许我们将GET或POST请求发送至Django视图,并接收返回数据,整个过程无需刷新当前页面。现代JavaScript提供了Fetch API,这是一种纯JavaScript方式,用于发送AJAX请求并处理响应。
接下来,我们将展示如何通过Fetch API发出GET和POST请求,从而在Django视图与前端模板之间高效传递JSON数据。
GET请求
- 通过获取发出GET请求
执行GET请求时,需向Fetch函数提供视图的URL以及适当的headers参数。请求发出后,视图返回数据,我们需要将响应转换为JSON格式,以便后续操作使用。
fetch(URL, {
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
URL
Fetch函数将URL作为其第一个参数。根据Django项目的URLconf配置及视图设置,URL可能包含关键字参数或查询字符串,我们需要利用这些参数在视图中筛选并获取所需数据。
Headers
设置AJAX请求的头部参数。由于希望视图以JSON格式返回数据,我们将Accept参数设置为application/json。同时,在视图中可能需要验证该请求是否为AJAX请求。通过添加值为“XMLHttpRequest”的“X-Requested-With”标头,视图即可识别并处理此类AJAX请求。
Fetch函数不会直接返回数据,而是返回一个response对象,该对象包含所请求的响应。为了获取实际数据,我们需要通过链式调用.then处理程序来处理response。第一个.then用于接收已解析的响应并将其转换为JSON对象;第二个.then则允许我们访问第一个.then返回的数据,进而执行后续操作,例如更新页面内容。
在视图中处理GET请求
我们需要创建一个视图来处理来自Fetch调用的AJAX请求。实现方式多样,其中一种简便方法是使用基于函数的视图,该视图接收请求并返回包含请求数据的JsonResponse。
# views.py
from django.http import JsonResponse
def 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)
如果通过包含附加参数的URL访问该视图,这些参数也将作为功能参数的一部分传入。系统将根据这些URL参数或查询字符串(若存在)从数据库中检索数据。在调用JsonResponse之前,务必确保已从django.http导入JsonResponse类。
该视图将返回JsonResponse,它将数据字典序列化为JSON格式并发送回前端页面,随后通过JavaScript中的链式处理程序进行解析。现在,我们可以利用JavaScript通过GET请求获取的数据来更新页面的特定部分。
POST请求
通过提取发出POST请求
与GET请求相比,POST请求需要配置更多的参数。
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
})
Method
Fetch默认发出GET请求。若要明确发出POST请求,必须通过添加method: 'POST'参数来指定。
Credentials
我们需要指定在请求中如何发送凭据。凭据处理较为复杂,特别是当项目的前端和后端分别托管在不同域名或端口时。如果AJAX请求与后端位于同一模板或同源环境中,可以使用默认值“same-origin”。这意味着,若所请求的URL与Fetch调用来自同一站点,用户凭据将在请求中自动发送。若前端和后端不在同一位置,则需配置不同的凭据策略,并需考虑跨域资源共享(CORS)问题。
Headers
“Accept”和“X-Requested-With”标头与GET请求相同,但POST请求必须额外包含“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');
获取到csrftoken后,我们将其作为“X-CSRFToken”的值添加到请求头中。
BODY
POST请求的主要目标是将数据发送至视图并更新数据库。因此,我们还需在Fetch调用中包含数据主体。假设我们要发送JSON数据,需添加body: JSON.stringify(data),其中data是要发送数据的JavaScript对象。除了JSON数据(包括文件和表单数据)外,其他类型的数据也可在正文中发送。有关包含其他类型数据的详细信息,请参阅MDN文档。
从POST请求获得的响应处理方式与GET请求相同,均通过链式Promise进行处理。
在视图中处理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模块。最终结果是获得一个包含通过Fetch发送数据的字典,随后可通过键名访问具体数据。
获取请求中的数据后,即可执行用户期望触发的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及更高版本
在Django 3.1版本(2020年8月发布)中,request.is_ajax()方法已被弃用。这意味着若我们要检查AJAX请求,必须自行重新实现该功能。幸运的是,Django开发人员提供了明确的替代方案。我们需要从request.is_ajax()方法的逻辑中自行重建检查功能,该逻辑仅包含一行代码:
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))
一些重要注意事项
尽管Fetch是发出AJAX请求的便捷方式,但并非所有浏览器(包括所有版本的Internet Explorer)都支持Fetch API。如果需要支持IE,请查阅jQuery或XMLHttpRequest来发出AJAX请求。
AJAX请求应仅限于Django项目中的小部分功能。如果发现自己在多个模板中频繁使用AJAX获取大量数据,建议考虑使用Django Rest Framework创建独立的API接口。
总结
通过在Django项目中使用AJAX请求,我们可以实现页面的局部更新而无需重新加载整个页面。Fetch API使得添加此功能变得相对简单,且所需的JavaScript代码最少。正确且谨慎地使用AJAX,可以使页面响应更快,并为用户提供更丰富的交互体验。
到此这篇关于如何利用AJAX获取Django后端数据的文章就介绍到这了,更多相关AJAX获取Django后端数据内容请搜索本站以前的文章或继续浏览下面的相关文章希望大家以后多多支持本站!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













