1660826160
AJAX, qui signifie JavaScript asynchrone et XML, est un ensemble de technologies utilisées côté client pour envoyer et récupérer des données du serveur de manière asynchrone.
AJAX nous permet d'apporter des modifications au contenu d'une page Web, sans nécessiter un rechargement de la page entière par l'utilisateur. Cela peut être utile, par exemple, pour l'auto-complétion dans une barre de recherche ou la validation d'un formulaire. Utilisé correctement, vous pouvez améliorer les performances de votre site, réduire la charge du serveur et améliorer l'expérience utilisateur globale.
Dans cet article, nous verrons des exemples d'exécution de requêtes GET, POST, PUT et DELETE AJAX dans Django. Bien que l'accent soit mis sur l'API Fetch, nous montrerons également des exemples jQuery.
AJAX est une pratique de programmation qui utilise l'objet XMLHttpRequest (XHR) pour communiquer avec un serveur de manière asynchrone et créer des pages Web dynamiques. Bien qu'AJAX et XMLHttpRequest soient souvent utilisés de manière interchangeable, ce sont des choses différentes.
Pour envoyer et recevoir des données vers et depuis un serveur Web, AJAX utilise les étapes suivantes :
AJAX peut être utilisé avec jQuery en utilisant la méthode ajax, mais l'API Fetch native est bien meilleure car elle a une interface propre et ne nécessite pas de bibliothèque tierce.
La structure générale de l'API Fetch ressemble à ceci :
fetch('http://some_url.com')
.then(response => response.json()) // converts the response to JSON
.then(data => {
console.log(data);
// do something (like update the DOM with the data)
});
Encore une fois, AJAX peut aider à améliorer les performances de votre site tout en réduisant la charge du serveur et en améliorant l'expérience utilisateur globale. Cela dit, cela ajoute beaucoup de complexité à votre application. Pour cette raison, à moins que vous n'utilisiez une application monopage (SPA) - comme React, Angular ou Vue - vous ne devriez vraiment utiliser AJAX que lorsque c'est absolument nécessaire.
Quelques exemples de cas où vous voudrez peut-être penser à utiliser AJAX :
En général, si le contenu doit être mis à jour beaucoup en fonction des interactions des utilisateurs, vous pouvez envisager d'utiliser AJAX pour gérer la mise à jour de certaines parties de la page Web plutôt que la page entière avec une actualisation de la page.
Les exemples de cet article peuvent être appliqués à n'importe quelle ressource CRUD. L'exemple de projet Django utilise todos comme ressource :
Méthode | URL | La description |
---|---|---|
OBTENIR | /todos/ | renvoie tout tout |
PUBLIER | /todos/ | S'ajoute à tous |
METTRE | /todos/<todo-id>/ | Mises à jour de tout |
EFFACER | /todos/<todo-id>/ | Supprimer à tout |
L'exemple de projet peut être trouvé sur GitHub :
Commençons par une simple requête GET pour récupérer des données.
Exemple:
fetch(url, {
method: "GET",
headers: {
"X-Requested-With": "XMLHttpRequest",
}
})
.then(response => response.json())
.then(data => {
console.log(data);
});
Le seul argument requis est l'URL de la ressource à partir de laquelle vous souhaitez récupérer les données. {% url %}
Si l'URL nécessite des arguments de mot-clé ou des chaînes de requête, vous pouvez utiliser la balise de Django .
Avez-vous remarqué l' X-Requested-With
en-tête ? Ceci est nécessaire pour informer le serveur que vous envoyez une requête AJAX.
fetch
renvoie une promesse contenant la réponse HTTP. Nous avons utilisé la .then
méthode pour d'abord extraire les données au format JSON de la réponse (via response.json()
) puis pour accéder aux données retournées. Dans l'exemple ci-dessus, nous venons de sortir les données dans la console.
https://github.com/testdriveio/django-ajax-xhr/blob/main/static/main.js#L19-L39
Code jQuery équivalent :
$.ajax({
url: url,
type: "GET",
dataType: "json",
success: (data) => {
console.log(data);
},
error: (error) => {
console.log(error);
}
});
https://github.com/testdriveio/django-ajax-xhr/blob/jquery/static/main.js#L19-L41
Du côté de Django, bien qu'il existe plusieurs façons de gérer les requêtes AJAX dans les vues, la plus simple consiste à utiliser une vue basée sur les fonctions :
from django.http import HttpResponseBadRequest, JsonResponse
from todos.models import Todo
def todos(request):
# request.is_ajax() is deprecated since django 3.1
is_ajax = request.headers.get('X-Requested-With') == 'XMLHttpRequest'
if is_ajax:
if request.method == 'GET':
todos = list(Todo.objects.all().values())
return JsonResponse({'context': todos})
return JsonResponse({'status': 'Invalid request'}, status=400)
else:
return HttpResponseBadRequest('Invalid request')
Dans cet exemple, notre ressource est todos. Ainsi, avant d'obtenir les todos de la base de données, nous avons vérifié que nous avons affaire à une requête AJAX et que la méthode de requête est GET. Si les deux sont vrais, nous sérialisons les données et envoyons une réponse à l'aide de la JsonResponse
classe. Puisqu'un QuerySet
objet n'est pas sérialisable JSON (les tâches, dans ce cas), nous avons utilisé la values
méthode pour renvoyer notre QuerySet sous forme de dictionnaire, puis l'avons enveloppé dans un fichier list
. Le résultat final est une liste de dicts.
https://github.com/testdriveio/django-ajax-xhr/blob/main/todos/views.py#L13-L28
Voyons ensuite comment gérer les requêtes POST.
Exemple:
fetch(url, {
method: "POST",
credentials: "same-origin",
headers: {
"X-Requested-With": "XMLHttpRequest",
"X-CSRFToken": getCookie("csrftoken"),
},
body: JSON.stringify({payload: "data to send"})
})
.then(response => response.json())
.then(data => {
console.log(data);
});
Nous devons spécifier comment nous voulons envoyer les informations d'identification dans la demande.
Dans le code ci-dessus, nous avons utilisé la valeur de "same-origin"
(la valeur par défaut) pour indiquer au navigateur d'envoyer les informations d'identification si l'URL demandée est sur la même origine que l'appel de récupération.
Dans le cas où le frontend et le backend sont hébergés sur des serveurs différents, vous devez définir ( credentials
qui "include"
envoie toujours les informations d'identification avec chaque demande) et activer le partage de ressources cross-origin dans le backend. Vous pouvez utiliser le package django-cors-headers pour ajouter des en-têtes CORS aux réponses dans une application Django.
Vous souhaitez en savoir plus sur la gestion des requêtes AJAX sur le même domaine et sur plusieurs domaines ? Consultez l' article Django Session-based Auth for Single Page Apps .
Cette fois, nous avons envoyé les données au serveur dans le body
de la demande.
Prenez note de l' X-CSRFToken
en-tête. Sans cela, vous obtiendriez une réponse 403 interdit du serveur dans le terminal :
Forbidden (CSRF token missing or incorrect.): /todos/
En effet, il est obligatoire d'inclure le jeton CSRF lors d'une requête POST pour empêcher les attaques Cross Site Request Forgery .
Nous pouvons inclure le jeton CSRF en définissant l' en- X-CSRFToken
tête de chacun XMLHttpRequest
sur la valeur du jeton CSRF.
La documentation de Django nous simplifie la vie en nous fournissant une fonction sympa qui nous permet d'acquérir le jeton :
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;
}
https://github.com/testdriveio/django-ajax-xhr/blob/main/static/main.js#L42-L56
La requête AJAX POST avec jQuery est assez similaire à la requête GET :
$.ajax({
url: url,
type: "POST",
dataType: "json",
data: JSON.stringify({payload: payload,}),
headers: {
"X-Requested-With": "XMLHttpRequest",
"X-CSRFToken": getCookie("csrftoken"), // don't forget to include the 'getCookie' function
},
success: (data) => {
console.log(data);
},
error: (error) => {
console.log(error);
}
});
https://github.com/testdriveio/django-ajax-xhr/blob/jquery/static/main.js#L44-L61
Côté serveur, la vue doit obtenir les données de la requête au format JSON, vous devrez donc utiliser le json
module pour le charger.
import json
from django.http import HttpResponseBadRequest, JsonResponse
from todos.models import Todo
def todos(request):
# request.is_ajax() is deprecated since django 3.1
is_ajax = request.headers.get('X-Requested-With') == 'XMLHttpRequest'
if is_ajax:
if request.method == 'POST':
data = json.load(request)
todo = data.get('payload')
Todo.objects.create(task=todo['task'], completed=todo['completed'])
return JsonResponse({'status': 'Todo added!'})
return JsonResponse({'status': 'Invalid request'}, status=400)
else:
return HttpResponseBadRequest('Invalid request')
Après avoir vérifié que nous avons affaire à une requête AJAX et que la méthode de requête est POST, nous avons désérialisé l'objet de requête et extrait l'objet de charge utile. Nous avons ensuite créé une nouvelle tâche et renvoyé la réponse appropriée.
https://github.com/testdriveio/django-ajax-xhr/blob/main/todos/views.py#L13-L28
Exemple:
fetch(url, {
method: "PUT",
credentials: "same-origin",
headers: {
"X-Requested-With": "XMLHttpRequest",
"X-CSRFToken": getCookie("csrftoken"), // don't forget to include the 'getCookie' function
},
body: JSON.stringify({payload: "data to send"})
})
.then(response => response.json())
.then(data => {
console.log(data);
});
Cela devrait ressembler à une requête POST. La seule différence est la forme de l'URL :
/todos/
/todos/<todo-id>/
https://github.com/testdriveio/django-ajax-xhr/blob/main/static/main.js#L59-L73
JQuery équivalent :
$.ajax({
url: url,
type: "PUT",
dataType: "json",
data: JSON.stringify({payload: payload,}),
headers: {
"X-Requested-With": "XMLHttpRequest",
"X-CSRFToken": getCookie("csrftoken"), // don't forget to include the 'getCookie' function
},
success: (data) => {
console.log(data);
},
error: (error) => {
console.log(error);
}
});
https://github.com/testdriveio/django-ajax-xhr/blob/jquery/static/main.js#L64-L81
Exemple:
import json
from django.http import HttpResponseBadRequest, JsonResponse
from django.shortcuts import get_object_or_404
from todos.models import Todo
def todo(request, todoId):
# request.is_ajax() is deprecated since django 3.1
is_ajax = request.headers.get('X-Requested-With') == 'XMLHttpRequest'
if is_ajax:
todo = get_object_or_404(Todo, id=todoId)
if request.method == 'PUT':
data = json.load(request)
updated_values = data.get('payload')
todo.task = updated_values['task']
todo.completed = updated_values['completed']
todo.save()
return JsonResponse({'status': 'Todo updated!'})
return JsonResponse({'status': 'Invalid request'}, status=400)
else:
return HttpResponseBadRequest('Invalid request')
https://github.com/testdriveio/django-ajax-xhr/blob/main/todos/views.py#L31-L53
Exemple:
fetch(url, {
method: "DELETE",
credentials: "same-origin",
headers: {
"X-Requested-With": "XMLHttpRequest",
"X-CSRFToken": getCookie("csrftoken"), // don't forget to include the 'getCookie' function
}
})
.then(response => response.json())
.then(data => {
console.log(data);
});
https://github.com/testdriveio/django-ajax-xhr/blob/main/static/main.js#L76-L89
Code jQuery :
$.ajax({
url: url,
type: "DELETE",
dataType: "json",
headers: {
"X-Requested-With": "XMLHttpRequest",
"X-CSRFToken": getCookie("csrftoken"),
},
success: (data) => {
console.log(data);
},
error: (error) => {
console.log(error);
}
});
https://github.com/testdriveio/django-ajax-xhr/blob/jquery/static/main.js#L84-L100
Voir:
from django.http import HttpResponseBadRequest, JsonResponse
from django.shortcuts import get_object_or_404
from todos.models import Todo
def todo(request, todoId):
# request.is_ajax() is deprecated since django 3.1
is_ajax = request.headers.get('X-Requested-With') == 'XMLHttpRequest'
if is_ajax:
todo = get_object_or_404(Todo, id=todoId)
if request.method == 'DELETE':
todo.delete()
return JsonResponse({'status': 'Todo deleted!'})
return JsonResponse({'status': 'Invalid request'}, status=400)
else:
return HttpResponseBadRequest('Invalid request')
https://github.com/testdriveio/django-ajax-xhr/blob/main/todos/views.py#L31-L53
AJAX nous permet d'effectuer des requêtes asynchrones pour modifier des parties d'une page sans avoir à recharger la page entière.
Dans cet article, vous avez vu en détail des exemples d'exécution de requêtes GET, POST, PUT et DELETE AJAX dans Django avec l'API Fetch et jQuery.
L'exemple de projet peut être trouvé sur GitHub :
Source : https://testdrive.io
1660812000
In this article, we'll look at examples of how to perform GET, POST, PUT, and DELETE AJAX requests in Django. While the focus will be on the Fetch API, we'll also show jQuery examples.
Source: https://testdriven.io
1660804740
AJAX, viết tắt của JavaScript và XML không đồng bộ, là một tập hợp các công nghệ được sử dụng ở phía máy khách để gửi và truy xuất dữ liệu từ máy chủ một cách không đồng bộ.
AJAX cho phép chúng tôi thực hiện các thay đổi đối với nội dung của trang web mà không yêu cầu người dùng tải lại toàn bộ trang. Điều này có thể hữu ích, chẳng hạn, để tự động hoàn thành trong thanh tìm kiếm hoặc xác thực biểu mẫu. Được sử dụng đúng cách, bạn có thể cải thiện hiệu suất trang web của mình, giảm tải máy chủ và cải thiện trải nghiệm người dùng tổng thể.
Trong bài viết này, chúng ta sẽ xem xét các ví dụ về cách thực hiện các yêu cầu GET, POST, PUT và DELETE AJAX trong Django. Trong khi trọng tâm sẽ là API Tìm nạp, chúng tôi cũng sẽ hiển thị các ví dụ về jQuery.
AJAX là một phương pháp lập trình sử dụng đối tượng XMLHttpRequest (XHR) để giao tiếp không đồng bộ với máy chủ và xây dựng các trang web động. Mặc dù AJAX và XMLHttpRequest thường được sử dụng thay thế cho nhau, nhưng chúng là những thứ khác nhau.
Để gửi và nhận dữ liệu đến và từ một máy chủ web, AJAX sử dụng các bước sau:
AJAX có thể được sử dụng với jQuery bằng cách sử dụng phương thức ajax, nhưng API Tìm nạp gốc tốt hơn nhiều vì nó có giao diện sạch sẽ và không yêu cầu thư viện của bên thứ ba.
Cấu trúc chung của API Tìm nạp trông như thế này:
fetch('http://some_url.com')
.then(response => response.json()) // converts the response to JSON
.then(data => {
console.log(data);
// do something (like update the DOM with the data)
});
Một lần nữa, AJAX có thể giúp cải thiện hiệu suất trang web của bạn trong khi giảm tải máy chủ và cải thiện trải nghiệm người dùng tổng thể. Điều đó nói rằng, nó làm tăng thêm rất nhiều sự phức tạp cho ứng dụng của bạn. Do đó, trừ khi bạn đang sử dụng Ứng dụng một trang (SPA) - như React, Angular hoặc Vue - bạn thực sự chỉ nên sử dụng AJAX khi thực sự cần thiết.
Một số ví dụ về thời điểm bạn có thể muốn nghĩ đến việc sử dụng AJAX:
Nói chung, nếu nội dung cần được cập nhật nhiều dựa trên tương tác của người dùng, bạn có thể muốn xem việc sử dụng AJAX để quản lý việc cập nhật các phần của trang web thay vì toàn bộ trang với tính năng làm mới trang.
Các ví dụ trong bài viết này có thể được áp dụng cho bất kỳ tài nguyên CRUD nào. Dự án Django ví dụ sử dụng todos làm tài nguyên:
Phương pháp | URL | Sự mô tả |
---|---|---|
LẤY | /todos/ | trả lại tất cả |
BƯU KIỆN | /todos/ | Thêm vào tất cả |
ĐẶT | /todos/<todo-id>/ | Cập nhật mọi thứ |
XÓA BỎ | /todos/<todo-id>/ | Xóa mọi thứ |
Bạn có thể tìm thấy dự án mẫu trên GitHub:
Hãy bắt đầu với một yêu cầu GET đơn giản để tìm nạp dữ liệu.
Thí dụ:
fetch(url, {
method: "GET",
headers: {
"X-Requested-With": "XMLHttpRequest",
}
})
.then(response => response.json())
.then(data => {
console.log(data);
});
Đối số bắt buộc duy nhất là URL cho tài nguyên mà bạn muốn tìm nạp dữ liệu. Nếu URL yêu cầu đối số từ khóa hoặc chuỗi truy vấn, bạn có thể sử dụng {% url %}
thẻ của Django.
Bạn có nhận thấy X-Requested-With
tiêu đề không? Điều này là cần thiết để thông báo cho máy chủ rằng bạn đang gửi một yêu cầu AJAX.
fetch
trả về một lời hứa có chứa phản hồi HTTP. Trước tiên , chúng tôi sử dụng .then
phương pháp để trích xuất dữ liệu ở định dạng JSON từ phản hồi (qua response.json()
) và sau đó để truy cập dữ liệu được trả về. Trong ví dụ trên, chúng tôi chỉ xuất dữ liệu trong bảng điều khiển.
https://github.com/testdrivenio/django-ajax-xhr/blob/main/static/main.js#L19-L39
Mã jQuery tương đương:
$.ajax({
url: url,
type: "GET",
dataType: "json",
success: (data) => {
console.log(data);
},
error: (error) => {
console.log(error);
}
});
https://github.com/testdrivenio/django-ajax-xhr/blob/jquery/static/main.js#L19-L41
Về mặt Django, mặc dù có một số cách để xử lý các yêu cầu AJAX trong các khung nhìn, nhưng cách đơn giản nhất là với một khung nhìn dựa trên chức năng:
from django.http import HttpResponseBadRequest, JsonResponse
from todos.models import Todo
def todos(request):
# request.is_ajax() is deprecated since django 3.1
is_ajax = request.headers.get('X-Requested-With') == 'XMLHttpRequest'
if is_ajax:
if request.method == 'GET':
todos = list(Todo.objects.all().values())
return JsonResponse({'context': todos})
return JsonResponse({'status': 'Invalid request'}, status=400)
else:
return HttpResponseBadRequest('Invalid request')
Trong ví dụ này, tài nguyên của chúng tôi là việc cần làm. Vì vậy, trước khi lấy các việc cần làm từ cơ sở dữ liệu, chúng tôi đã xác minh rằng chúng tôi đang xử lý một yêu cầu AJAX và phương thức yêu cầu là GET. Nếu cả hai đều đúng, chúng tôi đã tuần tự hóa dữ liệu và gửi phản hồi bằng cách sử dụng JsonResponse
lớp. Vì một QuerySet
đối tượng không thể tuần tự hóa JSON (trong trường hợp này là các việc cần làm), chúng tôi đã sử dụng values
phương thức để trả về QuerySet của chúng tôi dưới dạng từ điển và sau đó gói nó trong một list
. Kết quả cuối cùng là một danh sách các môn phái.
https://github.com/testdrivenio/django-ajax-xhr/blob/main/todos/views.py#L13-L28
Tiếp theo, hãy xem cách xử lý các yêu cầu POST.
Thí dụ:
fetch(url, {
method: "POST",
credentials: "same-origin",
headers: {
"X-Requested-With": "XMLHttpRequest",
"X-CSRFToken": getCookie("csrftoken"),
},
body: JSON.stringify({payload: "data to send"})
})
.then(response => response.json())
.then(data => {
console.log(data);
});
Chúng tôi cần chỉ định cách chúng tôi muốn gửi thông tin đăng nhập trong yêu cầu.
Trong đoạn mã trên, chúng tôi đã sử dụng giá trị của "same-origin"
(mặc định) để chỉ ra trình duyệt gửi thông tin đăng nhập nếu URL được yêu cầu có cùng nguồn gốc với lệnh gọi tìm nạp.
Trong trường hợp giao diện người dùng và phần phụ trợ được lưu trữ trên các máy chủ khác nhau, bạn phải đặt credentials
thành "include"
(luôn gửi thông tin đăng nhập với mỗi yêu cầu) và bật Chia sẻ tài nguyên đa nguồn trong phần phụ trợ. Bạn có thể sử dụng gói django-cors-headers để thêm tiêu đề CORS vào câu trả lời trong ứng dụng Django.
Bạn muốn tìm hiểu thêm về cách xử lý các yêu cầu AJAX trên cùng một miền và miền chéo? Xem lại bài viết Xác thực dựa trên phiên Django cho Ứng dụng trang đơn .
Lần này chúng tôi đã gửi dữ liệu đến máy chủ body
theo yêu cầu.
Hãy lưu ý đến X-CSRFToken
tiêu đề. Nếu không có nó, bạn sẽ nhận được phản hồi bị cấm 403 từ máy chủ trong thiết bị đầu cuối:
Forbidden (CSRF token missing or incorrect.): /todos/
Đó là vì bắt buộc phải bao gồm mã thông báo CSRF khi thực hiện yêu cầu ĐĂNG để ngăn chặn các cuộc tấn công Truy vấn Yêu cầu Trang web chéo .
Chúng tôi có thể bao gồm mã thông báo CSRF bằng cách đặt X-CSRFToken
tiêu đề trên mỗi XMLHttpRequest
mã thành giá trị của mã thông báo CSRF.
Tài liệu Django đơn giản hóa cuộc sống của chúng tôi bằng cách cung cấp cho chúng tôi một chức năng tuyệt vời cho phép chúng tôi có được mã thông báo :
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;
}
https://github.com/testdrivenio/django-ajax-xhr/blob/main/static/main.js#L42-L56
Yêu cầu AJAX POST với jQuery khá giống với yêu cầu GET:
$.ajax({
url: url,
type: "POST",
dataType: "json",
data: JSON.stringify({payload: payload,}),
headers: {
"X-Requested-With": "XMLHttpRequest",
"X-CSRFToken": getCookie("csrftoken"), // don't forget to include the 'getCookie' function
},
success: (data) => {
console.log(data);
},
error: (error) => {
console.log(error);
}
});
https://github.com/testdrivenio/django-ajax-xhr/blob/jquery/static/main.js#L44-L61
Ở phía máy chủ, chế độ xem cần lấy dữ liệu từ yêu cầu ở định dạng JSON, vì vậy bạn sẽ cần sử dụng json
mô-đun để tải nó.
import json
from django.http import HttpResponseBadRequest, JsonResponse
from todos.models import Todo
def todos(request):
# request.is_ajax() is deprecated since django 3.1
is_ajax = request.headers.get('X-Requested-With') == 'XMLHttpRequest'
if is_ajax:
if request.method == 'POST':
data = json.load(request)
todo = data.get('payload')
Todo.objects.create(task=todo['task'], completed=todo['completed'])
return JsonResponse({'status': 'Todo added!'})
return JsonResponse({'status': 'Invalid request'}, status=400)
else:
return HttpResponseBadRequest('Invalid request')
Sau khi xác minh rằng chúng tôi đang xử lý một yêu cầu AJAX và phương thức yêu cầu là POST, chúng tôi đã giải nén đối tượng yêu cầu và trích xuất đối tượng payload. Sau đó, chúng tôi đã tạo một việc cần làm mới và gửi lại phản hồi thích hợp.
https://github.com/testdrivenio/django-ajax-xhr/blob/main/todos/views.py#L13-L28
Thí dụ:
fetch(url, {
method: "PUT",
credentials: "same-origin",
headers: {
"X-Requested-With": "XMLHttpRequest",
"X-CSRFToken": getCookie("csrftoken"), // don't forget to include the 'getCookie' function
},
body: JSON.stringify({payload: "data to send"})
})
.then(response => response.json())
.then(data => {
console.log(data);
});
Điều này sẽ trông giống như một yêu cầu ĐĂNG. Sự khác biệt duy nhất là hình dạng của URL:
/todos/
/todos/<todo-id>/
https://github.com/testdrivenio/django-ajax-xhr/blob/main/static/main.js#L59-L73
JQuery tương đương:
$.ajax({
url: url,
type: "PUT",
dataType: "json",
data: JSON.stringify({payload: payload,}),
headers: {
"X-Requested-With": "XMLHttpRequest",
"X-CSRFToken": getCookie("csrftoken"), // don't forget to include the 'getCookie' function
},
success: (data) => {
console.log(data);
},
error: (error) => {
console.log(error);
}
});
https://github.com/testdrivenio/django-ajax-xhr/blob/jquery/static/main.js#L64-L81
Thí dụ:
import json
from django.http import HttpResponseBadRequest, JsonResponse
from django.shortcuts import get_object_or_404
from todos.models import Todo
def todo(request, todoId):
# request.is_ajax() is deprecated since django 3.1
is_ajax = request.headers.get('X-Requested-With') == 'XMLHttpRequest'
if is_ajax:
todo = get_object_or_404(Todo, id=todoId)
if request.method == 'PUT':
data = json.load(request)
updated_values = data.get('payload')
todo.task = updated_values['task']
todo.completed = updated_values['completed']
todo.save()
return JsonResponse({'status': 'Todo updated!'})
return JsonResponse({'status': 'Invalid request'}, status=400)
else:
return HttpResponseBadRequest('Invalid request')
https://github.com/testdrivenio/django-ajax-xhr/blob/main/todos/views.py#L31-L53
Thí dụ:
fetch(url, {
method: "DELETE",
credentials: "same-origin",
headers: {
"X-Requested-With": "XMLHttpRequest",
"X-CSRFToken": getCookie("csrftoken"), // don't forget to include the 'getCookie' function
}
})
.then(response => response.json())
.then(data => {
console.log(data);
});
https://github.com/testdrivenio/django-ajax-xhr/blob/main/static/main.js#L76-L89
mã jQuery:
$.ajax({
url: url,
type: "DELETE",
dataType: "json",
headers: {
"X-Requested-With": "XMLHttpRequest",
"X-CSRFToken": getCookie("csrftoken"),
},
success: (data) => {
console.log(data);
},
error: (error) => {
console.log(error);
}
});
https://github.com/testdrivenio/django-ajax-xhr/blob/jquery/static/main.js#L84-L100
Lượt xem:
from django.http import HttpResponseBadRequest, JsonResponse
from django.shortcuts import get_object_or_404
from todos.models import Todo
def todo(request, todoId):
# request.is_ajax() is deprecated since django 3.1
is_ajax = request.headers.get('X-Requested-With') == 'XMLHttpRequest'
if is_ajax:
todo = get_object_or_404(Todo, id=todoId)
if request.method == 'DELETE':
todo.delete()
return JsonResponse({'status': 'Todo deleted!'})
return JsonResponse({'status': 'Invalid request'}, status=400)
else:
return HttpResponseBadRequest('Invalid request')
https://github.com/testdrivenio/django-ajax-xhr/blob/main/todos/views.py#L31-L53
AJAX cho phép chúng tôi thực hiện các yêu cầu không đồng bộ để thay đổi các phần của trang mà không cần phải tải lại toàn bộ trang.
Trong bài viết này, bạn đã xem chi tiết các ví dụ về cách thực hiện các yêu cầu GET, POST, PUT và DELETE AJAX trong Django với API tìm nạp và jQuery.
Bạn có thể tìm thấy dự án mẫu trên GitHub:
Nguồn: https://testdriven.io
1660797480
AJAX, что означает асинхронный JavaScript и XML, представляет собой набор технологий, используемых на стороне клиента для асинхронной отправки и получения данных с сервера.
AJAX позволяет нам вносить изменения в содержимое веб-страницы, не требуя от пользователя перезагрузки всей страницы. Это может быть полезно, например, для автодополнения в строке поиска или проверки формы. При правильном использовании вы можете повысить производительность своего сайта, снизить нагрузку на сервер и улучшить общее взаимодействие с пользователем.
В этой статье мы рассмотрим примеры выполнения запросов GET, POST, PUT и DELETE AJAX в Django. Хотя основное внимание будет уделено Fetch API, мы также покажем примеры jQuery.
AJAX — это метод программирования, который использует объект XMLHttpRequest (XHR) для асинхронной связи с сервером и создания динамических веб-страниц. Хотя AJAX и XMLHttpRequest часто используются взаимозаменяемо, это разные вещи.
Для отправки и получения данных на веб-сервер и с него AJAX использует следующие шаги:
AJAX можно использовать с jQuery с помощью метода ajax, но собственный API Fetch намного лучше, поскольку он имеет понятный интерфейс и не требует сторонней библиотеки.
Общая структура Fetch API выглядит так:
fetch('http://some_url.com')
.then(response => response.json()) // converts the response to JSON
.then(data => {
console.log(data);
// do something (like update the DOM with the data)
});
Опять же, AJAX может помочь повысить производительность вашего сайта, одновременно снизив нагрузку на сервер и улучшив общее взаимодействие с пользователем. Тем не менее, это значительно усложняет ваше приложение. Из-за этого, если вы не используете одностраничное приложение (SPA), такое как React, Angular или Vue, вам действительно следует использовать AJAX только тогда, когда это абсолютно необходимо.
Несколько примеров, когда вы можете подумать об использовании AJAX:
В общем, если содержимое необходимо часто обновлять в зависимости от взаимодействия с пользователем, вы можете рассмотреть возможность использования AJAX для управления обновлением частей веб-страницы, а не всей страницы с обновлением страницы.
Примеры в этой статье можно применить к любому ресурсу CRUD. Пример проекта Django использует todos в качестве ресурса:
Метод | URL-адрес | Описание |
---|---|---|
ПОЛУЧИТЬ | /todos/ | возвращает все все |
ПОЧТА | /todos/ | Добавляет ко всем |
ПОМЕЩАТЬ | /todos/<todo-id>/ | Обновления для всего |
УДАЛИТЬ | /todos/<todo-id>/ | Удалить ко всему |
Пример проекта можно найти на GitHub:
Начнем с простого запроса GET для получения данных.
Пример:
fetch(url, {
method: "GET",
headers: {
"X-Requested-With": "XMLHttpRequest",
}
})
.then(response => response.json())
.then(data => {
console.log(data);
});
Единственный обязательный аргумент — это URL-адрес ресурса, из которого вы хотите получить данные. Если для URL-адреса требуются аргументы ключевого слова или строки запроса, вы можете использовать {% url %}
тег Django.
Вы заметили X-Requested-With
заголовок? Это необходимо, чтобы сообщить серверу, что вы отправляете запрос AJAX.
fetch
возвращает обещание, содержащее HTTP-ответ. Мы использовали этот .then
метод, чтобы сначала извлечь данные в формате JSON из ответа (через response.json()
), а затем получить доступ к возвращенным данным. В приведенном выше примере мы просто вывели данные в консоль.
https://github.com/testdrivenio/django-ajax-xhr/blob/main/static/main.js#L19-L39
Эквивалентный код jQuery:
$.ajax({
url: url,
type: "GET",
dataType: "json",
success: (data) => {
console.log(data);
},
error: (error) => {
console.log(error);
}
});
https://github.com/testdrivenio/django-ajax-xhr/blob/jquery/static/main.js#L19-L41
Что касается Django, то хотя существует несколько способов обработки запросов AJAX в представлениях, самый простой — это представление на основе функций:
from django.http import HttpResponseBadRequest, JsonResponse
from todos.models import Todo
def todos(request):
# request.is_ajax() is deprecated since django 3.1
is_ajax = request.headers.get('X-Requested-With') == 'XMLHttpRequest'
if is_ajax:
if request.method == 'GET':
todos = list(Todo.objects.all().values())
return JsonResponse({'context': todos})
return JsonResponse({'status': 'Invalid request'}, status=400)
else:
return HttpResponseBadRequest('Invalid request')
В этом примере наш ресурс — todos. Итак, прежде чем получить задачи из базы данных, мы убедились, что имеем дело с запросом AJAX и что метод запроса — GET. Если оба верны, мы сериализовали данные и отправили ответ, используя JsonResponse
класс. Поскольку QuerySet
объект не сериализуем JSON (в данном случае todos), мы использовали этот values
метод для возврата нашего QuerySet в виде словаря, а затем завернули его в файл list
. Конечным результатом является список диктов.
https://github.com/testdrivenio/django-ajax-xhr/blob/main/todos/views.py#L13-L28
Далее давайте посмотрим, как обрабатывать запросы POST.
Пример:
fetch(url, {
method: "POST",
credentials: "same-origin",
headers: {
"X-Requested-With": "XMLHttpRequest",
"X-CSRFToken": getCookie("csrftoken"),
},
body: JSON.stringify({payload: "data to send"})
})
.then(response => response.json())
.then(data => {
console.log(data);
});
Нам нужно указать, как мы хотим отправить учетные данные в запросе.
В приведенном выше коде мы использовали значение "same-origin"
(по умолчанию), чтобы указать браузеру отправлять учетные данные, если запрошенный URL-адрес находится в том же источнике, что и вызов выборки.
В случае, когда интерфейс и серверная часть размещены на разных серверах, вам нужно установить credentials
( "include"
что всегда отправляет учетные данные с каждым запросом) и включить совместное использование ресурсов между источниками в серверной части. Вы можете использовать пакет django-cors-headers , чтобы добавить заголовки CORS к ответам в приложении Django.
Хотите узнать больше о том, как обрабатывать запросы AJAX в одном и том же домене и между доменами? Ознакомьтесь со статьей Аутентификация на основе сеанса Django для одностраничных приложений .
На этот раз мы отправили данные на сервер в body
запросе.
Обратите внимание на X-CSRFToken
заголовок. Без него вы бы получили 403 запрещенный ответ от сервера в терминале:
Forbidden (CSRF token missing or incorrect.): /todos/
Это связано с тем, что при отправке запроса POST необходимо включать токен CSRF для предотвращения атак с подделкой межсайтовых запросов .
Мы можем включить токен CSRF, установив для X-CSRFToken
каждого заголовка XMLHttpRequest
значение токена CSRF.
Документация Django упрощает нашу жизнь, предоставляя нам удобную функцию, позволяющую получить токен :
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;
}
https://github.com/testdrivenio/django-ajax-xhr/blob/main/static/main.js#L42-L56
Запрос AJAX POST с jQuery очень похож на запрос GET:
$.ajax({
url: url,
type: "POST",
dataType: "json",
data: JSON.stringify({payload: payload,}),
headers: {
"X-Requested-With": "XMLHttpRequest",
"X-CSRFToken": getCookie("csrftoken"), // don't forget to include the 'getCookie' function
},
success: (data) => {
console.log(data);
},
error: (error) => {
console.log(error);
}
});
https://github.com/testdrivenio/django-ajax-xhr/blob/jquery/static/main.js#L44-L61
На стороне сервера представление должно получать данные из запроса в формате JSON, поэтому вам нужно будет использовать json
модуль, чтобы загрузить его.
import json
from django.http import HttpResponseBadRequest, JsonResponse
from todos.models import Todo
def todos(request):
# request.is_ajax() is deprecated since django 3.1
is_ajax = request.headers.get('X-Requested-With') == 'XMLHttpRequest'
if is_ajax:
if request.method == 'POST':
data = json.load(request)
todo = data.get('payload')
Todo.objects.create(task=todo['task'], completed=todo['completed'])
return JsonResponse({'status': 'Todo added!'})
return JsonResponse({'status': 'Invalid request'}, status=400)
else:
return HttpResponseBadRequest('Invalid request')
Убедившись, что мы имеем дело с запросом AJAX и что метод запроса — POST, мы десериализовали объект запроса и извлекли объект полезной нагрузки. Затем мы создали новую задачу и отправили соответствующий ответ.
https://github.com/testdrivenio/django-ajax-xhr/blob/main/todos/views.py#L13-L28
Пример:
fetch(url, {
method: "PUT",
credentials: "same-origin",
headers: {
"X-Requested-With": "XMLHttpRequest",
"X-CSRFToken": getCookie("csrftoken"), // don't forget to include the 'getCookie' function
},
body: JSON.stringify({payload: "data to send"})
})
.then(response => response.json())
.then(data => {
console.log(data);
});
Это должно быть похоже на POST-запрос. Единственная разница заключается в форме URL:
/todos/
/todos/<todo-id>/
https://github.com/testdrivenio/django-ajax-xhr/blob/main/static/main.js#L59-L73
Эквивалентный jQuery:
$.ajax({
url: url,
type: "PUT",
dataType: "json",
data: JSON.stringify({payload: payload,}),
headers: {
"X-Requested-With": "XMLHttpRequest",
"X-CSRFToken": getCookie("csrftoken"), // don't forget to include the 'getCookie' function
},
success: (data) => {
console.log(data);
},
error: (error) => {
console.log(error);
}
});
https://github.com/testdrivenio/django-ajax-xhr/blob/jquery/static/main.js#L64-L81
Пример:
import json
from django.http import HttpResponseBadRequest, JsonResponse
from django.shortcuts import get_object_or_404
from todos.models import Todo
def todo(request, todoId):
# request.is_ajax() is deprecated since django 3.1
is_ajax = request.headers.get('X-Requested-With') == 'XMLHttpRequest'
if is_ajax:
todo = get_object_or_404(Todo, id=todoId)
if request.method == 'PUT':
data = json.load(request)
updated_values = data.get('payload')
todo.task = updated_values['task']
todo.completed = updated_values['completed']
todo.save()
return JsonResponse({'status': 'Todo updated!'})
return JsonResponse({'status': 'Invalid request'}, status=400)
else:
return HttpResponseBadRequest('Invalid request')
https://github.com/testdrivenio/django-ajax-xhr/blob/main/todos/views.py#L31-L53
Пример:
fetch(url, {
method: "DELETE",
credentials: "same-origin",
headers: {
"X-Requested-With": "XMLHttpRequest",
"X-CSRFToken": getCookie("csrftoken"), // don't forget to include the 'getCookie' function
}
})
.then(response => response.json())
.then(data => {
console.log(data);
});
https://github.com/testdrivenio/django-ajax-xhr/blob/main/static/main.js#L76-L89
JQuery-код:
$.ajax({
url: url,
type: "DELETE",
dataType: "json",
headers: {
"X-Requested-With": "XMLHttpRequest",
"X-CSRFToken": getCookie("csrftoken"),
},
success: (data) => {
console.log(data);
},
error: (error) => {
console.log(error);
}
});
https://github.com/testdrivenio/django-ajax-xhr/blob/jquery/static/main.js#L84-L100
Вид:
from django.http import HttpResponseBadRequest, JsonResponse
from django.shortcuts import get_object_or_404
from todos.models import Todo
def todo(request, todoId):
# request.is_ajax() is deprecated since django 3.1
is_ajax = request.headers.get('X-Requested-With') == 'XMLHttpRequest'
if is_ajax:
todo = get_object_or_404(Todo, id=todoId)
if request.method == 'DELETE':
todo.delete()
return JsonResponse({'status': 'Todo deleted!'})
return JsonResponse({'status': 'Invalid request'}, status=400)
else:
return HttpResponseBadRequest('Invalid request')
https://github.com/testdrivenio/django-ajax-xhr/blob/main/todos/views.py#L31-L53
AJAX позволяет нам выполнять асинхронные запросы на изменение частей страницы без перезагрузки всей страницы.
В этой статье вы подробно рассмотрели примеры того, как выполнять запросы GET, POST, PUT и DELETE AJAX в Django с помощью Fetch API и jQuery.
Пример проекта можно найти на GitHub:
Источник: https://testdriven.io
1660790220
AJAX 代表異步 JavaScript 和 XML,是一組用於客戶端的技術,用於從服務器異步發送和檢索數據。
AJAX 允許我們對網頁內容進行更改,而無需用戶重新加載整個頁面。例如,這對於搜索欄中的自動完成或表單驗證很有用。正確使用,您可以提高網站的性能、減少服務器負載並改善整體用戶體驗。
在本文中,我們將看看如何在 Django 中執行 GET、POST、PUT 和 DELETE AJAX 請求的示例。雖然重點將放在 Fetch API 上,但我們還將展示 jQuery 示例。
AJAX 是一種編程實踐,它使用 XMLHttpRequest (XHR) 對象與服務器異步通信並構建動態網頁。雖然 AJAX 和 XMLHttpRequest 經常互換使用,但它們是不同的東西。
為了向 Web 服務器發送和接收數據,AJAX 使用以下步驟:
AJAX 可以通過使用 ajax 方法與 jQuery 一起使用,但原生 Fetch API 更好,因為它具有乾淨的接口並且不需要第三方庫。
Fetch API 的一般結構如下所示:
fetch('http://some_url.com').then(response => response.json()) // converts the response to JSON.then(data => { console.log(data); // do something (like update the DOM with the data)});
同樣,AJAX 可以幫助提高站點的性能,同時降低服務器負載並改善整體用戶體驗。也就是說,它為您的應用程序增加了很多複雜性。正因為如此,除非您使用的是單頁應用程序(SPA)——比如 React、Angular 或 Vue——你真的應該只在絕對必要時才使用 AJAX。
您可能想考慮使用 AJAX 的一些示例:
一般來說,如果內容需要根據用戶交互進行大量更新,您可能需要考慮使用 AJAX 來管理網頁的更新部分,而不是使用頁面刷新來管理整個頁面。
本文中的示例可以應用於任何 CRUD 資源。示例 Django 項目使用 todos 作為它的資源:
方法 | 網址 | 描述 |
---|---|---|
得到 | /todos/ | 全部返回 |
郵政 | /todos/ | 添加到所有 |
放 | /todos/<todo-id>/ | 更新一切 |
刪除 | /todos/<todo-id>/ | 刪除所有內容 |
示例項目可以在 GitHub 上找到:
讓我們從一個簡單的獲取數據的 GET 請求開始。
例子:
fetch(url, { method: "GET", headers: { "X-Requested-With": "XMLHttpRequest", }}).then(response => response.json()).then(data => { console.log(data);});
唯一需要的參數是您希望從中獲取數據的資源的 URL。如果 URL 需要關鍵字參數或查詢字符串,您可以使用 Django 的{% url %}
標籤。
注意到X-Requested-With
標題了嗎?這是通知服務器您正在發送 AJAX 請求所必需的。
fetch
returns a promise containing the HTTP response. We used the .then
method to first extract the data in JSON format from the response (via response.json()
) and then to access the data returned. In the example above, we just outputted the data in the console.
https://github.com/testdrivenio/django-ajax-xhr/blob/main/static/main.js#L19-L39
Equivalent jQuery code:
$.ajax({ url: url, type: "GET", dataType: "json", success: (data) => { console.log(data); }, error: (error) => { console.log(error); }});
https://github.com/testdrivenio/django-ajax-xhr/blob/jquery/static/main.js#L19-L41
On the Django side of things, while there are several ways to handle AJAX requests in the views, the simplest is with a function-based view:
from django.http import HttpResponseBadRequest, JsonResponsefrom todos.models import Tododef todos(request): # request.is_ajax() is deprecated since django 3.1 is_ajax = request.headers.get('X-Requested-With') == 'XMLHttpRequest' if is_ajax: if request.method == 'GET': todos = list(Todo.objects.all().values()) return JsonResponse({'context': todos}) return JsonResponse({'status': 'Invalid request'}, status=400) else: return HttpResponseBadRequest('Invalid request')
在這個例子中,我們的資源是 todos。因此,在從數據庫中獲取 todos 之前,我們驗證了我們正在處理 AJAX 請求並且請求方法是 GET。JsonResponse
如果兩者都為真,我們將數據序列化並使用該類發送響應。由於對QuerySet
像不是 JSON 可序列化的(在本例中為 todos),因此我們使用該values
方法將 QuerySet 作為字典返回,然後將其包裝在list
. 最終結果是一個字典列表。
https://github.com/testdrivenio/django-ajax-xhr/blob/main/todos/views.py#L13-L28
接下來,讓我們看看如何處理 POST 請求。
例子:
fetch(url, { method: "POST", credentials: "same-origin", headers: { "X-Requested-With": "XMLHttpRequest", "X-CSRFToken": getCookie("csrftoken"), }, body: JSON.stringify({payload: "data to send"})}).then(response => response.json()).then(data => { console.log(data);});
我們需要指定我們希望如何在請求中發送憑證。
在上面的代碼中,"same-origin"
如果請求的 URL 與 fetch 調用在同一源上,我們使用(默認值)的值來指示瀏覽器發送憑據。
如果前端和後端託管在不同的服務器上,您必須設置credentials
為"include"
(始終隨每個請求發送憑據)並在後端啟用跨域資源共享。您可以使用django-cors-headers包將 CORS 標頭添加到 Django 應用程序中的響應中。
想了解更多關於如何處理同域和跨域的 AJAX 請求?查看單頁應用程序的基於 Django 會話的身份驗證文章。
這一次我們在請求中將數據發送到服務器body
。
注意X-CSRFToken
標題。沒有它,您將在終端中從服務器收到 403 禁止響應:
Forbidden (CSRF token missing or incorrect.): /todos/
這是因為在發出 POST 請求時必須包含 CSRF 令牌以防止跨站點請求偽造攻擊。
我們可以通過將X-CSRFToken
每個標頭設置為 CSRF 令牌XMLHttpRequest
的值來包含 CSRF 令牌。
Django 文檔通過為我們提供一個很好的函數來簡化我們的生活,讓我們可以獲取令牌:
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;}
https://github.com/testdrivenio/django-ajax-xhr/blob/main/static/main.js#L42-L56
使用 jQuery 的 AJAX POST 請求與 GET 請求非常相似:
$.ajax({ url: url, type: "POST", dataType: "json", data: JSON.stringify({payload: payload,}), headers: { "X-Requested-With": "XMLHttpRequest", "X-CSRFToken": getCookie("csrftoken"), // don't forget to include the 'getCookie' function }, success: (data) => { console.log(data); }, error: (error) => { console.log(error); }});
https://github.com/testdrivenio/django-ajax-xhr/blob/jquery/static/main.js#L44-L61
在服務器端,視圖需要從請求中獲取 JSON 格式的數據,因此您需要使用json
模塊來加載它。
import jsonfrom django.http import HttpResponseBadRequest, JsonResponsefrom todos.models import Tododef todos(request): # request.is_ajax() is deprecated since django 3.1 is_ajax = request.headers.get('X-Requested-With') == 'XMLHttpRequest' if is_ajax: if request.method == 'POST': data = json.load(request) todo = data.get('payload') Todo.objects.create(task=todo['task'], completed=todo['completed']) return JsonResponse({'status': 'Todo added!'}) return JsonResponse({'status': 'Invalid request'}, status=400) else: return HttpResponseBadRequest('Invalid request')
在驗證我們正在處理 AJAX 請求並且請求方法是 POST 之後,我們反序列化了請求對象並提取了有效負載對象。然後,我們創建了一個新的待辦事項並發回了適當的響應。
https://github.com/testdrivenio/django-ajax-xhr/blob/main/todos/views.py#L13-L28
例子:
fetch(url, { method: "PUT", credentials: "same-origin", headers: { "X-Requested-With": "XMLHttpRequest", "X-CSRFToken": getCookie("csrftoken"), // don't forget to include the 'getCookie' function }, body: JSON.stringify({payload: "data to send"})}).then(response => response.json()).then(data => { console.log(data);});
這應該類似於 POST 請求。唯一的區別是 URL 的形狀:
/todos/
/todos/<todo-id>/
https://github.com/testdrivenio/django-ajax-xhr/blob/main/static/main.js#L59-L73
等效的 jQuery:
$.ajax({ url: url, type: "PUT", dataType: "json", data: JSON.stringify({payload: payload,}), headers: { "X-Requested-With": "XMLHttpRequest", "X-CSRFToken": getCookie("csrftoken"), // don't forget to include the 'getCookie' function }, success: (data) => { console.log(data); }, error: (error) => { console.log(error); }});
https://github.com/testdrivenio/django-ajax-xhr/blob/jquery/static/main.js#L64-L81
例子:
import jsonfrom django.http import HttpResponseBadRequest, JsonResponsefrom django.shortcuts import get_object_or_404from todos.models import Tododef todo(request, todoId): # request.is_ajax() is deprecated since django 3.1 is_ajax = request.headers.get('X-Requested-With') == 'XMLHttpRequest' if is_ajax: todo = get_object_or_404(Todo, id=todoId) if request.method == 'PUT': data = json.load(request) updated_values = data.get('payload') todo.task = updated_values['task'] todo.completed = updated_values['completed'] todo.save() return JsonResponse({'status': 'Todo updated!'}) return JsonResponse({'status': 'Invalid request'}, status=400) else: return HttpResponseBadRequest('Invalid request')
https://github.com/testdrivenio/django-ajax-xhr/blob/main/todos/views.py#L31-L53
例子:
fetch(url, { method: "DELETE", credentials: "same-origin", headers: { "X-Requested-With": "XMLHttpRequest", "X-CSRFToken": getCookie("csrftoken"), // don't forget to include the 'getCookie' function }}).then(response => response.json()).then(data => { console.log(data);});
https://github.com/testdrivenio/django-ajax-xhr/blob/main/static/main.js#L76-L89
jQuery代碼:
$.ajax({ url: url, type: "DELETE", dataType: "json", headers: { "X-Requested-With": "XMLHttpRequest", "X-CSRFToken": getCookie("csrftoken"), }, success: (data) => { console.log(data); }, error: (error) => { console.log(error); }});
https://github.com/testdrivenio/django-ajax-xhr/blob/jquery/static/main.js#L84-L100
看法:
from django.http import HttpResponseBadRequest, JsonResponsefrom django.shortcuts import get_object_or_404from todos.models import Tododef todo(request, todoId): # request.is_ajax() is deprecated since django 3.1 is_ajax = request.headers.get('X-Requested-With') == 'XMLHttpRequest' if is_ajax: todo = get_object_or_404(Todo, id=todoId) if request.method == 'DELETE': todo.delete() return JsonResponse({'status': 'Todo deleted!'}) return JsonResponse({'status': 'Invalid request'}, status=400) else: return HttpResponseBadRequest('Invalid request')
https://github.com/testdrivenio/django-ajax-xhr/blob/main/todos/views.py#L31-L53
AJAX 允許我們執行異步請求來更改頁面的某些部分,而無需重新加載整個頁面。
在本文中,您詳細了解瞭如何使用 Fetch API 和 jQuery 在 Django 中執行 GET、POST、PUT 和 DELETE AJAX 請求的示例。
示例項目可以在 GitHub 上找到:
1660775700
AJAX, que significa JavaScript asíncrono y XML, es un conjunto de tecnologías utilizadas en el lado del cliente para enviar y recuperar datos del servidor de forma asíncrona.
AJAX nos permite realizar cambios en el contenido de una página web, sin necesidad de que el usuario vuelva a cargar toda la página. Esto puede ser útil, por ejemplo, para autocompletar en una barra de búsqueda o validación de formularios. Usado correctamente, puede mejorar el rendimiento de su sitio, disminuir la carga del servidor y mejorar la experiencia general del usuario.
En este artículo, veremos ejemplos de cómo realizar solicitudes GET, POST, PUT y DELETE AJAX en Django. Si bien el enfoque estará en la API Fetch, también mostraremos ejemplos de jQuery.
AJAX es una práctica de programación que utiliza el objeto XMLHttpRequest (XHR) para comunicarse con un servidor de forma asíncrona y crear páginas web dinámicas. Aunque AJAX y XMLHttpRequest a menudo se usan indistintamente, son cosas diferentes.
Para enviar y recibir datos hacia y desde un servidor web, AJAX utiliza los siguientes pasos:
AJAX se puede usar con jQuery usando el método ajax, pero la API Fetch nativa es mucho mejor ya que tiene una interfaz limpia y no requiere una biblioteca de terceros.
La estructura general de la API Fetch se ve así:
fetch('http://some_url.com')
.then(response => response.json()) // converts the response to JSON
.then(data => {
console.log(data);
// do something (like update the DOM with the data)
});
Una vez más, AJAX puede ayudar a mejorar el rendimiento de su sitio al tiempo que reduce la carga del servidor y mejora la experiencia general del usuario. Dicho esto, agrega mucha complejidad a su aplicación. Debido a esto, a menos que esté utilizando una aplicación de página única (SPA), como React, Angular o Vue, solo debe usar AJAX cuando sea absolutamente necesario.
Algunos ejemplos de cuándo puede pensar en usar AJAX:
En general, si el contenido necesita actualizarse mucho en función de las interacciones del usuario, es posible que desee considerar el uso de AJAX para administrar la actualización de partes de la página web en lugar de la página completa con una actualización de página.
Los ejemplos de este artículo se pueden aplicar a cualquier recurso CRUD. El proyecto Django de ejemplo usa todos como su recurso:
Método | URL | Descripción |
---|---|---|
OBTENER | /todos/ | devuelve todo todo |
CORREO | /todos/ | se suma a todos |
PONER | /todos/<todo-id>/ | Updates a todo |
ELIMINAR | /todos/<todo-id>/ | Deletes a todo |
El proyecto de ejemplo se puede encontrar en GitHub:
Comencemos con una simple solicitud GET para obtener datos.
Ejemplo:
fetch(url, {
method: "GET",
headers: {
"X-Requested-With": "XMLHttpRequest",
}
})
.then(response => response.json())
.then(data => {
console.log(data);
});
El único argumento obligatorio es la URL del recurso del que desea obtener los datos. Si la URL requiere argumentos de palabras clave o cadenas de consulta, puede usar la {% url %}
etiqueta de Django.
¿Te fijaste en el X-Requested-With
encabezado? Esto es necesario para informar al servidor que está enviando una solicitud AJAX.
fetch
devuelve una promesa que contiene la respuesta HTTP. Usamos el .then
método para extraer primero los datos en formato JSON de la respuesta (a través de response.json()
) y luego para acceder a los datos devueltos. En el ejemplo anterior, acabamos de mostrar los datos en la consola.
https://github.com/testdrivenio/django-ajax-xhr/blob/main/static/main.js#L19-L39
Código jQuery equivalente:
$.ajax({
url: url,
type: "GET",
dataType: "json",
success: (data) => {
console.log(data);
},
error: (error) => {
console.log(error);
}
});
https://github.com/testdrivenio/django-ajax-xhr/blob/jquery/static/main.js#L19-L41
En el lado de Django, si bien hay varias formas de manejar las solicitudes AJAX en las vistas, la más simple es con una vista basada en funciones:
from django.http import HttpResponseBadRequest, JsonResponse
from todos.models import Todo
def todos(request):
# request.is_ajax() is deprecated since django 3.1
is_ajax = request.headers.get('X-Requested-With') == 'XMLHttpRequest'
if is_ajax:
if request.method == 'GET':
todos = list(Todo.objects.all().values())
return JsonResponse({'context': todos})
return JsonResponse({'status': 'Invalid request'}, status=400)
else:
return HttpResponseBadRequest('Invalid request')
En este ejemplo, nuestro recurso es todos. Entonces, antes de obtener los todos de la base de datos, verificamos que estamos tratando con una solicitud AJAX y que el método de solicitud es GET. Si ambos son ciertos, serializamos los datos y enviamos una respuesta usando la JsonResponse
clase. Dado que un QuerySet
objeto no es JSON serializable (todos, en este caso), usamos el values
método para devolver nuestro QuerySet como un diccionario y luego lo envolvimos en un archivo list
. El resultado final es una lista de dictados.
https://github.com/testdrivenio/django-ajax-xhr/blob/main/todos/views.py#L13-L28
A continuación, veamos cómo manejar las solicitudes POST.
Ejemplo:
fetch(url, {
method: "POST",
credentials: "same-origin",
headers: {
"X-Requested-With": "XMLHttpRequest",
"X-CSRFToken": getCookie("csrftoken"),
},
body: JSON.stringify({payload: "data to send"})
})
.then(response => response.json())
.then(data => {
console.log(data);
});
Necesitamos especificar cómo queremos enviar las credenciales en la solicitud.
En el código anterior, usamos el valor de "same-origin"
(el valor predeterminado) para indicarle al navegador que envíe las credenciales si la URL solicitada está en el mismo origen que la llamada de búsqueda.
En el caso de que el frontend y el backend estén alojados en diferentes servidores, deberá configurar ( credentials
que "include"
siempre envía las credenciales con cada solicitud) y habilitar el uso compartido de recursos de origen cruzado en el backend. Puede usar el paquete django-cors-headers para agregar encabezados CORS a las respuestas en una aplicación Django.
¿Desea obtener más información sobre cómo manejar las solicitudes AJAX en el mismo dominio y entre dominios? Revise el artículo Autenticación basada en sesiones de Django para aplicaciones de una sola página .
Esta vez enviamos los datos al servidor en el body
de la solicitud.
Toma nota del X-CSRFToken
encabezado. Sin él, obtendría una respuesta prohibida 403 del servidor en la terminal:
Forbidden (CSRF token missing or incorrect.): /todos/
Esto se debe a que es obligatorio incluir el token CSRF al realizar una solicitud POST para evitar ataques de falsificación de solicitudes entre sitios .
Podemos incluir el token CSRF configurando el X-CSRFToken
encabezado de cada uno XMLHttpRequest
con el valor del token CSRF.
La documentación de Django simplifica nuestras vidas al proporcionarnos una función agradable que nos permite adquirir el token :
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;
}
https://github.com/testdrivenio/django-ajax-xhr/blob/main/static/main.js#L42-L56
La solicitud AJAX POST con jQuery es bastante similar a la solicitud GET:
$.ajax({
url: url,
type: "POST",
dataType: "json",
data: JSON.stringify({payload: payload,}),
headers: {
"X-Requested-With": "XMLHttpRequest",
"X-CSRFToken": getCookie("csrftoken"), // don't forget to include the 'getCookie' function
},
success: (data) => {
console.log(data);
},
error: (error) => {
console.log(error);
}
});
https://github.com/testdrivenio/django-ajax-xhr/blob/jquery/static/main.js#L44-L61
En el lado del servidor, la vista necesita obtener los datos de la solicitud en formato JSON, por lo que deberá usar el json
módulo para cargarlo.
import json
from django.http import HttpResponseBadRequest, JsonResponse
from todos.models import Todo
def todos(request):
# request.is_ajax() is deprecated since django 3.1
is_ajax = request.headers.get('X-Requested-With') == 'XMLHttpRequest'
if is_ajax:
if request.method == 'POST':
data = json.load(request)
todo = data.get('payload')
Todo.objects.create(task=todo['task'], completed=todo['completed'])
return JsonResponse({'status': 'Todo added!'})
return JsonResponse({'status': 'Invalid request'}, status=400)
else:
return HttpResponseBadRequest('Invalid request')
Después de verificar que estamos tratando con una solicitud AJAX y que el método de solicitud es POST, deserializamos el objeto de solicitud y extrajimos el objeto de carga útil. Luego creamos un nuevo todo y enviamos la respuesta apropiada.
https://github.com/testdrivenio/django-ajax-xhr/blob/main/todos/views.py#L13-L28
Ejemplo:
fetch(url, {
method: "PUT",
credentials: "same-origin",
headers: {
"X-Requested-With": "XMLHttpRequest",
"X-CSRFToken": getCookie("csrftoken"), // don't forget to include the 'getCookie' function
},
body: JSON.stringify({payload: "data to send"})
})
.then(response => response.json())
.then(data => {
console.log(data);
});
Esto debería parecerse a una solicitud POST. La única diferencia es la forma de la URL:
/todos/
/todos/<todo-id>/
https://github.com/testdrivenio/django-ajax-xhr/blob/main/static/main.js#L59-L73
jQuery equivalente:
$.ajax({
url: url,
type: "PUT",
dataType: "json",
data: JSON.stringify({payload: payload,}),
headers: {
"X-Requested-With": "XMLHttpRequest",
"X-CSRFToken": getCookie("csrftoken"), // don't forget to include the 'getCookie' function
},
success: (data) => {
console.log(data);
},
error: (error) => {
console.log(error);
}
});
https://github.com/testdrivenio/django-ajax-xhr/blob/jquery/static/main.js#L64-L81
Ejemplo:
import json
from django.http import HttpResponseBadRequest, JsonResponse
from django.shortcuts import get_object_or_404
from todos.models import Todo
def todo(request, todoId):
# request.is_ajax() is deprecated since django 3.1
is_ajax = request.headers.get('X-Requested-With') == 'XMLHttpRequest'
if is_ajax:
todo = get_object_or_404(Todo, id=todoId)
if request.method == 'PUT':
data = json.load(request)
updated_values = data.get('payload')
todo.task = updated_values['task']
todo.completed = updated_values['completed']
todo.save()
return JsonResponse({'status': 'Todo updated!'})
return JsonResponse({'status': 'Invalid request'}, status=400)
else:
return HttpResponseBadRequest('Invalid request')
https://github.com/testdrivenio/django-ajax-xhr/blob/main/todos/views.py#L31-L53
Ejemplo:
fetch(url, {
method: "DELETE",
credentials: "same-origin",
headers: {
"X-Requested-With": "XMLHttpRequest",
"X-CSRFToken": getCookie("csrftoken"), // don't forget to include the 'getCookie' function
}
})
.then(response => response.json())
.then(data => {
console.log(data);
});
https://github.com/testdrivenio/django-ajax-xhr/blob/main/static/main.js#L76-L89
Código jQuery:
$.ajax({
url: url,
type: "DELETE",
dataType: "json",
headers: {
"X-Requested-With": "XMLHttpRequest",
"X-CSRFToken": getCookie("csrftoken"),
},
success: (data) => {
console.log(data);
},
error: (error) => {
console.log(error);
}
});
https://github.com/testdrivenio/django-ajax-xhr/blob/jquery/static/main.js#L84-L100
Vista:
from django.http import HttpResponseBadRequest, JsonResponse
from django.shortcuts import get_object_or_404
from todos.models import Todo
def todo(request, todoId):
# request.is_ajax() is deprecated since django 3.1
is_ajax = request.headers.get('X-Requested-With') == 'XMLHttpRequest'
if is_ajax:
todo = get_object_or_404(Todo, id=todoId)
if request.method == 'DELETE':
todo.delete()
return JsonResponse({'status': 'Todo deleted!'})
return JsonResponse({'status': 'Invalid request'}, status=400)
else:
return HttpResponseBadRequest('Invalid request')
https://github.com/testdrivenio/django-ajax-xhr/blob/main/todos/views.py#L31-L53
AJAX nos permite realizar solicitudes asincrónicas para cambiar partes de una página sin tener que volver a cargar la página completa.
En este artículo, vio, en detalle, ejemplos de cómo realizar solicitudes GET, POST, PUT y DELETE AJAX en Django con Fetch API y jQuery.
El proyecto de ejemplo se puede encontrar en GitHub:
Fuente: https://testdriven.io
1660767360
AJAX, que significa JavaScript e XML assíncrono, é um conjunto de tecnologias usadas no lado do cliente para enviar e recuperar dados do servidor de forma assíncrona.
AJAX nos permite realizar alterações no conteúdo de uma página web, sem a necessidade de recarregar a página inteira pelo usuário. Isso pode ser útil, por exemplo, para preenchimento automático em uma barra de pesquisa ou validação de formulário. Usado corretamente, você pode melhorar o desempenho do seu site, diminuir a carga do servidor e melhorar a experiência geral do usuário.
Neste artigo, veremos exemplos de como executar solicitações GET, POST, PUT e DELETE AJAX no Django. Embora o foco seja a API Fetch, também mostraremos exemplos de jQuery.
AJAX é uma prática de programação que usa o objeto XMLHttpRequest (XHR) para se comunicar com um servidor de forma assíncrona e construir páginas da web dinâmicas. Embora AJAX e XMLHttpRequest sejam frequentemente usados de forma intercambiável, eles são coisas diferentes.
Para enviar e receber dados de e para um servidor web, o AJAX usa as seguintes etapas:
AJAX pode ser usado com jQuery usando o método ajax, mas a API nativa Fetch é muito melhor, pois possui uma interface limpa e não requer uma biblioteca de terceiros.
A estrutura geral da API Fetch é assim:
fetch('http://some_url.com')
.then(response => response.json()) // converts the response to JSON
.then(data => {
console.log(data);
// do something (like update the DOM with the data)
});
Novamente, o AJAX pode ajudar a melhorar o desempenho do seu site enquanto diminui a carga do servidor e melhora a experiência geral do usuário. Dito isso, ele adiciona muita complexidade ao seu aplicativo. Por causa disso, a menos que você esteja usando um aplicativo de página única (SPA) - como React, Angular ou Vue - você só deve usar AJAX quando for absolutamente necessário.
Alguns exemplos de quando você pode querer pensar em usar AJAX:
Em geral, se o conteúdo precisar ser muito atualizado com base nas interações do usuário, convém usar o AJAX para gerenciar partes de atualização da página da Web em vez de toda a página com uma atualização de página.
Os exemplos neste artigo podem ser aplicados a qualquer recurso CRUD. O exemplo de projeto Django usa todos como recurso:
Método | URL | Descrição |
---|---|---|
PEGUE | /todos/ | Returns all todos |
PUBLICAR | /todos/ | Adds a todo |
COLOCAR | /todos/<todo-id>/ | Atualizações de tudo |
EXCLUIR | /todos/<todo-id>/ | Excluir para tudo |
O projeto de exemplo pode ser encontrado no GitHub:
Vamos começar com uma solicitação GET simples para buscar dados.
Exemplo:
fetch(url, {
method: "GET",
headers: {
"X-Requested-With": "XMLHttpRequest",
}
})
.then(response => response.json())
.then(data => {
console.log(data);
});
O único argumento obrigatório é o URL do recurso do qual você deseja buscar os dados. Se a URL requer argumentos de palavras-chave ou strings de consulta, você pode usar a {% url %}
tag do Django.
Você reparou no X-Requested-With
cabeçalho? Isso é necessário para informar ao servidor que você está enviando uma solicitação AJAX.
fetch
retorna uma promessa contendo a resposta HTTP. Usamos o .then
método para primeiro extrair os dados no formato JSON da resposta (via response.json()
) e depois acessar os dados retornados. No exemplo acima, acabamos de gerar os dados no console.
https://github.com/testdrivedio/django-ajax-xhr/blob/main/static/main.js#L19-L39
Código jQuery equivalente:
$.ajax({
url: url,
type: "GET",
dataType: "json",
success: (data) => {
console.log(data);
},
error: (error) => {
console.log(error);
}
});
https://github.com/testdrivedio/django-ajax-xhr/blob/jquery/static/main.js#L19-L41
No lado do Django, embora existam várias maneiras de lidar com solicitações AJAX nas visualizações, a mais simples é com uma visualização baseada em função:
from django.http import HttpResponseBadRequest, JsonResponse
from todos.models import Todo
def todos(request):
# request.is_ajax() is deprecated since django 3.1
is_ajax = request.headers.get('X-Requested-With') == 'XMLHttpRequest'
if is_ajax:
if request.method == 'GET':
todos = list(Todo.objects.all().values())
return JsonResponse({'context': todos})
return JsonResponse({'status': 'Invalid request'}, status=400)
else:
return HttpResponseBadRequest('Invalid request')
Neste exemplo, nosso recurso é todos. Então, antes de pegar os todos do banco de dados, verificamos que estamos lidando com uma requisição AJAX e que o método da requisição é GET. Se ambos forem verdadeiros, serializamos os dados e enviamos uma resposta usando a JsonResponse
classe. Como um QuerySet
objeto não é serializável em JSON (os todos, neste caso), usamos o values
método para retornar nosso QuerySet como um dicionário e, em seguida, o envolvemos em um arquivo list
. O resultado final é uma lista de dicts.
https://github.com/testdrivedio/django-ajax-xhr/blob/main/todos/views.py#L13-L28
Em seguida, vamos ver como lidar com solicitações POST.
Exemplo:
fetch(url, {
method: "POST",
credentials: "same-origin",
headers: {
"X-Requested-With": "XMLHttpRequest",
"X-CSRFToken": getCookie("csrftoken"),
},
body: JSON.stringify({payload: "data to send"})
})
.then(response => response.json())
.then(data => {
console.log(data);
});
Precisamos especificar como queremos enviar as credenciais na solicitação.
No código acima, usamos o valor de "same-origin"
(o padrão) para indicar ao navegador para enviar as credenciais se a URL solicitada está na mesma origem da chamada de busca.
No caso de o frontend e o backend estarem hospedados em servidores diferentes, você teria que configurar credentials
para "include"
(que sempre envia as credenciais a cada solicitação) e habilitar o Cross-Origin Resource Sharing no backend. Você pode usar o pacote django-cors-headers para adicionar cabeçalhos CORS às respostas em um aplicativo Django.
Quer saber mais sobre como lidar com solicitações AJAX no mesmo domínio e entre domínios? Revise o artigo Autenticação baseada em sessão do Django para aplicativos de página única .
Desta vez enviamos os dados para o servidor na body
requisição.
Tome nota do X-CSRFToken
cabeçalho. Sem ele, você obteria uma resposta 403 proibida do servidor no terminal:
Forbidden (CSRF token missing or incorrect.): /todos/
Isso porque é obrigatório incluir o token CSRF ao fazer uma solicitação POST para evitar ataques Cross Site Request Forgery .
Podemos incluir o token CSRF definindo o X-CSRFToken
cabeçalho de cada um XMLHttpRequest
com o valor do token CSRF.
A documentação do Django simplifica nossas vidas nos fornecendo uma boa função que nos permite adquirir o token :
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;
}
https://github.com/testdrivedio/django-ajax-xhr/blob/main/static/main.js#L42-L56
A solicitação POST AJAX com jQuery é bastante semelhante à solicitação GET:
$.ajax({
url: url,
type: "POST",
dataType: "json",
data: JSON.stringify({payload: payload,}),
headers: {
"X-Requested-With": "XMLHttpRequest",
"X-CSRFToken": getCookie("csrftoken"), // don't forget to include the 'getCookie' function
},
success: (data) => {
console.log(data);
},
error: (error) => {
console.log(error);
}
});
https://github.com/testdrivedio/django-ajax-xhr/blob/jquery/static/main.js#L44-L61
No lado do servidor, a visualização precisa obter os dados da solicitação no formato JSON, portanto, você precisará usar o json
módulo para carregá-lo.
import json
from django.http import HttpResponseBadRequest, JsonResponse
from todos.models import Todo
def todos(request):
# request.is_ajax() is deprecated since django 3.1
is_ajax = request.headers.get('X-Requested-With') == 'XMLHttpRequest'
if is_ajax:
if request.method == 'POST':
data = json.load(request)
todo = data.get('payload')
Todo.objects.create(task=todo['task'], completed=todo['completed'])
return JsonResponse({'status': 'Todo added!'})
return JsonResponse({'status': 'Invalid request'}, status=400)
else:
return HttpResponseBadRequest('Invalid request')
Depois de verificar que estamos lidando com uma solicitação AJAX e que o método de solicitação é POST, desserializamos o objeto de solicitação e extraímos o objeto de carga útil. Em seguida, criamos um novo todo e enviamos de volta a resposta apropriada.
https://github.com/testdrivedio/django-ajax-xhr/blob/main/todos/views.py#L13-L28
Exemplo:
fetch(url, {
method: "PUT",
credentials: "same-origin",
headers: {
"X-Requested-With": "XMLHttpRequest",
"X-CSRFToken": getCookie("csrftoken"), // don't forget to include the 'getCookie' function
},
body: JSON.stringify({payload: "data to send"})
})
.then(response => response.json())
.then(data => {
console.log(data);
});
Isso deve ser semelhante a uma solicitação POST. A única diferença é a forma do URL:
/todos/
/todos/<todo-id>/
https://github.com/testdrivedio/django-ajax-xhr/blob/main/static/main.js#L59-L73
jQuery equivalente:
$.ajax({
url: url,
type: "PUT",
dataType: "json",
data: JSON.stringify({payload: payload,}),
headers: {
"X-Requested-With": "XMLHttpRequest",
"X-CSRFToken": getCookie("csrftoken"), // don't forget to include the 'getCookie' function
},
success: (data) => {
console.log(data);
},
error: (error) => {
console.log(error);
}
});
https://github.com/testdrivedio/django-ajax-xhr/blob/jquery/static/main.js#L64-L81
Exemplo:
import json
from django.http import HttpResponseBadRequest, JsonResponse
from django.shortcuts import get_object_or_404
from todos.models import Todo
def todo(request, todoId):
# request.is_ajax() is deprecated since django 3.1
is_ajax = request.headers.get('X-Requested-With') == 'XMLHttpRequest'
if is_ajax:
todo = get_object_or_404(Todo, id=todoId)
if request.method == 'PUT':
data = json.load(request)
updated_values = data.get('payload')
todo.task = updated_values['task']
todo.completed = updated_values['completed']
todo.save()
return JsonResponse({'status': 'Todo updated!'})
return JsonResponse({'status': 'Invalid request'}, status=400)
else:
return HttpResponseBadRequest('Invalid request')
https://github.com/testdrivedio/django-ajax-xhr/blob/main/todos/views.py#L31-L53
Exemplo:
fetch(url, {
method: "DELETE",
credentials: "same-origin",
headers: {
"X-Requested-With": "XMLHttpRequest",
"X-CSRFToken": getCookie("csrftoken"), // don't forget to include the 'getCookie' function
}
})
.then(response => response.json())
.then(data => {
console.log(data);
});
https://github.com/testdrivedio/django-ajax-xhr/blob/main/static/main.js#L76-L89
código jQuery:
$.ajax({
url: url,
type: "DELETE",
dataType: "json",
headers: {
"X-Requested-With": "XMLHttpRequest",
"X-CSRFToken": getCookie("csrftoken"),
},
success: (data) => {
console.log(data);
},
error: (error) => {
console.log(error);
}
});
https://github.com/testdrivedio/django-ajax-xhr/blob/jquery/static/main.js#L84-L100
Visão:
from django.http import HttpResponseBadRequest, JsonResponse
from django.shortcuts import get_object_or_404
from todos.models import Todo
def todo(request, todoId):
# request.is_ajax() is deprecated since django 3.1
is_ajax = request.headers.get('X-Requested-With') == 'XMLHttpRequest'
if is_ajax:
todo = get_object_or_404(Todo, id=todoId)
if request.method == 'DELETE':
todo.delete()
return JsonResponse({'status': 'Todo deleted!'})
return JsonResponse({'status': 'Invalid request'}, status=400)
else:
return HttpResponseBadRequest('Invalid request')
https://github.com/testdrivedio/django-ajax-xhr/blob/main/todos/views.py#L31-L53
AJAX nos permite realizar solicitações assíncronas para alterar partes de uma página sem precisar recarregar a página inteira.
Neste artigo, você viu, em detalhes, exemplos de como executar solicitações GET, POST, PUT e DELETE AJAX no Django com a API Fetch e jQuery.
O projeto de exemplo pode ser encontrado no GitHub:
Fonte: https://testdrive.io
1659885360
👋 Welcome to render_async
render_async
is here to make your pages show faster to users.Pages become faster seamlessly by rendering partials to your views.
Partials render asynchronously and let users see your page faster than using regular rendering.
It works with Rails and its tools out of the box.
:sparkles: A quick overview of how render_async
does its magic:
render_async
makes an AJAX request on the controller actionrender_async
view helperJavaScript is injected straight into <%= content_for :render_async %>
so you choose where to put it.
:mega: P.S. Join our Discord channel for help and discussion, and let's make render_async
even better!
Add this line to your application's Gemfile:
gem 'render_async'
And then execute:
$ bundle install
Include render_async
view helper somewhere in your views (e.g. app/views/comments/show.html.erb
):
<%= render_async comment_stats_path %>
Then create a route for it config/routes.rb
:
get :comment_stats, controller: :comments
Fill in the logic in your controller (e.g. app/controllers/comments_controller.rb
):
def comment_stats
@stats = Comment.get_stats
render partial: "comment_stats"
end
Create a partial that will render (e.g. app/views/comments/_comment_stats.html.erb
):
<div class="col-md-6">
<%= @stats %>
</div>
Add content_for
in your base view file in the body part (e.g. app/views/layouts/application.html.erb
):
<%= content_for :render_async %>
Advanced usage includes information on different options, such as:
render_async
renders an element that gets replaced with the content of your request response. In order to have more control over the element that renders first (before the request), you can set the ID of that element.
To set ID of the container element, you can do the following:
<%= render_async users_path, container_id: 'users-container' %>
Rendered code in the view:
<div id="users-container">
</div>
...
render_async
renders an element that gets replaced with the content of your request response. If you want to style that element, you can set the class name on it.
<%= render_async users_path, container_class: 'users-container-class' %>
Rendered code in the view:
<div id="render_async_18b8a6cd161499117471" class="users-container-class">
</div>
...
render_async
can accept html_options
as a hash. html_options
is an optional hash that gets passed to a Rails' javascript_tag
, to drop HTML tags into the script
element.
Example of utilizing html_options
with a nonce:
<%= render_async users_path, html_options: { nonce: true } %>
Rendered code in the view:
<script nonce="2x012CYGxKgM8qAApxRHxA==">
//<![CDATA[
...
//]]>
</script>
...
<div id="render_async_18b8a6cd161499117471" class="">
</div>
:bulb: You can enable
nonce
to be set everywhere by using configuration option render_async provides.
render_async
can take in an HTML element name, allowing you to control what type of container gets rendered. This can be useful when you're using render_async
inside a table and you need it to render a tr
element before your request gets loaded, so your content doesn't get pushed out of the table.
Example of using HTML element name:
<%= render_async users_path, html_element_name: 'tr' %>
Rendered code in the view:
<tr id="render_async_04229e7abe1507987376">
</tr>
...
render_async
can be called with a block that will act as a placeholder before your AJAX call finishes.
Example of passing in a block:
<%= render_async users_path do %>
<h1>Users are loading...</h1>
<% end %>
Rendered code in the view:
<div id="render_async_14d7ac165d1505993721">
<h1>Users are loading...</h1>
</div>
<script>
//<![CDATA[
...
//]]>
</script>
After AJAX is finished, placeholder will be replaced with the request's response.
render_async
can receive :event_name
option which will emit JavaScript event after it's done with fetching and rendering request content to HTML.
This can be useful to have if you want to add some JavaScript functionality after your partial is loaded through render_async
.
You can also access the associated container (DOM node) in the event object that gets emitted.
Example of passing it to render_async
:
<%= render_async users_path, event_name: "users-loaded" %>
Rendered code in view:
<div id="render_async_04229e7abe1507987376">
</div>
<script>
//<![CDATA[
...
document.dispatchEvent(new Event("users-loaded"));
...
//]]>
</script>
Then, in your JavaScript code, you could do something like this:
document.addEventListener("users-loaded", function(event) {
console.log("Users have loaded!", event.container); // Access the container which loaded the users
});
:bulb: Dispatching events is also supported for older browsers that don't support Event constructor.
render_async
will fire the event render_async_load
when an async partial has loaded and rendered on the page.
In case there is an error, the event render_async_error
will fire instead.
This event will fire for all render_async
partials on the page. For every event, the associated container (DOM node) will be passed along.
This can be useful to apply JavaScript to content loaded after the page is ready.
Example of using events:
// Vanilla javascript
document.addEventListener('render_async_load', function(event) {
console.log('Async partial loaded in this container:', event.container);
});
document.addEventListener('render_async_error', function(event) {
console.log('Async partial could not load in this container:', event.container);
});
// with jQuery
$(document).on('render_async_load', function(event) {
console.log('Async partial loaded in this container:', event.container);
});
$(document).on('render_async_error', function(event) {
console.log('Async partial could not load in this container:', event.container);
});
render_async
lets you refresh (reload) the partial by letting you dispatch the 'refresh' event on the render_async
's container. An example:
<%= render_async comments_path,
container_id: 'refresh-me',
replace_container: false %>
<button id="refresh-button">Refresh comments</button>
<script>
var button = document.getElementById('refresh-button')
var container = document.getElementById('refresh-me');
button.addEventListener('click', function() {
var event = new Event('refresh');
// Dispatch 'refresh' on the render_async container
container.dispatchEvent(event)
})
</script>
If you follow the example above, when you click "Refresh comments" button, render_async
will trigger again and reload the comments_path
.
:bulb: Note that you need to pass
replace_container: false
so you can later dispatch an event on that container.
render_async
can retry your requests if they fail for some reason.
If you want render_async
to retry a request for number of times, you can do this:
<%= render_async users_path, retry_count: 5, error_message: "Couldn't fetch it" %>
Now render_async will retry users_path
for 5 times. If it succeeds in between, it will stop with dispatching requests. If it fails after 5 times, it will show an error message which you need to specify.
This can show useful when you know your requests often fail, and you don't want to refresh the whole page just to retry them.
If you want to retry requests but with some delay in between the calls, you can pass a retry_delay
option together with retry_count
like so:
<%= render_async users_path,
retry_count: 5,
retry_delay: 2000 %>
This will make render_async
wait for 2 seconds before retrying after each failure. In the end, if the request is still failing after 5th time, it will dispatch a default error event.
:candy: If you are catching an event after an error, you can get
retryCount
from the event.retryCount
will have the number of retries it took before the event was dispatched.
Here is an example on how to get retryCount
:
<%= render_async users_path,
retry_count: 5,
retry_delay: 2000,
error_event_name: 'it-failed-badly' %>
<script>
document.addEventListener('it-failed-badly', function(event) {
console.log("Request failed after " + event.retryCount + " tries!")
});
</script>
If you need to pass retry count to the backend, you can pass retry_count_header
in render_async
's options:
<%= render_async users_path,
retry_count: 5,
retry_count_header: 'Retry-Count-Current' %>
And then in controller you can read the value from request headers.
request.headers['Retry-Count-Current']&.to_i
You can trigger render_async
loading by clicking or doing another event to a certain HTML element. You can do this by passing in a selector and an event name which will trigger render_async
. If you don't specify an event name, the default event that will trigger render_async
will be 'click' event. You can do this by doing the following:
<a href='#' id='comments-button'>Load comments</a>
<%= render_async comments_path, toggle: { selector: '#comments-button', event: :click } %>
This will trigger render_async
to load the comments_path
when you click the #comments-button
element. If you want to remove an event once it's triggered, you can pass once: true
in the toggle options. The once
option is false (nil
) by default.
You can also pass in a placeholder before the render_async
is triggered. That way, the element that started render_async
logic will be removed after the request has been completed. You can achieve this behaviour with something like this:
<%= render_async comments_path, toggle: { selector: '#comments-button', event: :click } do %>
<a href='#' id='comments-button'>Load comments</a>
<% end %>
Also, you can mix interval and toggle features. This way, you can turn polling on, and off by clicking the "Load comments" button. In order to do this, you need to pass toggle
and interval
arguments to render_async
call like this:
<a href='#' id='comments-button'>Load comments</a>
<%= render_async comments_path, toggle: { selector: '#comments-button', event: :click }, interval: 2000 %>
If you want render_async
to render the request on load, you can pass start: true
. Passing the start
option inside the toggle
hash will trigger render_async
on page load. You can then toggle off polling by interacting with the element you specified. An example:
<a href='#' id='comments-button'>Toggle comments loading</a>
<%= render_async comments_path,
toggle: { selector: '#comments-button',
event: :click,
start: true },
interval: 2000 %>
In the example above, the comments will load as soon as the page is rendered. Then, you can stop polling for comments by clicking the "Toggle comments loading" button.
You can call render_async
with interval argument. This will make render_async call specified path at the specified interval.
By doing this:
<%= render_async comments_path, interval: 5000 %>
You are telling render_async
to fetch comments_path every 5 seconds.
This can be handy if you want to enable polling for a specific URL.
:warning: By passing interval to
render_async
, the initial container element will remain in the HTML tree and it will not be replaced with request response. You can handle how that container element is rendered and its style by passing in an HTML element name and HTML element class.
You can controller render_async
polling in 2 manners. First one is pretty simple, and it involves using the toggle feature. To do this, you can follow instructions in the control polling with a toggle section.
The second option is more advanced and it involves emitting events to the render_async
's container element. From your code, you can emit the following events:
:bulb: Please note that events need to be dispatched to a render_async container.
An example of how you can do this looks like this:
<%= render_async wave_render_async_path,
container_id: 'controllable-interval', # set container_id so we can get it later easily
interval: 3000 %>
<button id='stop-polling'>Stop polling</button>
<button id='start-polling'>Start polling</button>
<script>
var container = document.getElementById('controllable-interval')
var stopPolling = document.getElementById('stop-polling')
var startPolling = document.getElementById('start-polling')
var triggerEventOnContainer = function(eventName) {
var event = new Event(eventName);
container.dispatchEvent(event)
}
stopPolling.addEventListener('click', function() {
container.innerHTML = '<p>Polling stopped</p>'
triggerEventOnContainer('async-stop')
})
startPolling.addEventListener('click', function() {
triggerEventOnContainer('async-start')
})
</script>
We are rendering two buttons - "Stop polling" and "Start polling". Then, we attach an event listener to catch any clicking on the buttons. When the buttons are clicked, we either stop the polling or start the polling, depending on which button a user clicks.
render_async
lets you handle errors by allowing you to pass in error_message
and error_event_name
.
error_message
passing an error_message
will render a message if the AJAX requests fails for some reason
<%= render_async users_path,
error_message: '<p>Sorry, users loading went wrong :(</p>' %>
error_event_name
calling render_async
with error_event_name
will dispatch event in the case of an error with your AJAX call.
You can then catch the event in your code with:
document.addEventListener('users-error-event', function() {
// I'm on it
})
<%= render_asyc users_path, error_event_name: 'users-error-event' %>
render_async
can utilize view fragment caching to avoid extra AJAX calls.
In your views (e.g. app/views/comments/show.html.erb
):
# note 'render_async_cache' instead of standard 'render_async'
<%= render_async_cache comment_stats_path %>
Then, in the partial (e.g. app/views/comments/_comment_stats.html.erb
):
<% cache render_async_cache_key(request.path), skip_digest: true do %>
<div class="col-md-6">
<%= @stats %>
</div>
<% end %>
:expires_in
in your view where you cache the partialBy default, render_async
creates AJAX GET requests for the path you provide. If you want to change this behaviour, you can pass in a method
argument to render_async
view helper.
<%= render_async users_path, method: 'POST' %>
You can also set body
and headers
of the request if you need them.
<%= render_async users_path,
method: 'POST',
data: { fresh: 'AF' },
headers: { 'Content-Type': 'text' } %>
On Turbolinks applications, you may experience caching issues when navigating away from, and then back to, a page with a render_async
call on it. This will likely show up as an empty div.
If you're using Turbolinks 5 or higher, you can resolve this by setting Turbolinks configuration of render_async
to true:
RenderAsync.configure do |config|
config.turbolinks = true # Enable this option if you are using Turbolinks 5+
end
This way, you're not breaking Turbolinks flow of loading or reloading a page. It is more efficient than the next option below.
Another option: If you want, you can tell Turbolinks to reload your render_async
call as follows:
<%= render_async events_path, html_options: { 'data-turbolinks-track': 'reload' } %>
This will reload the whole page with Turbolinks.
:bulb: If Turbolinks is misbehaving in some way, make sure to put
<%= content_for :render_async %>
in your base view file in the<body>
and not the<head>
.
On Turbo applications, you may experience caching issues when navigating away from, and then back to, a page with a render_async
call on it. This will likely show up as an empty div.
If you're using Turbo, you can resolve this by setting Turbo configuration of render_async
to true:
RenderAsync.configure do |config|
config.turbo = true # Enable this option if you are using Turbo
end
This way, you're not breaking Turbos flow of loading or reloading a page. It is more efficient than the next option below.
Another option: If you want, you can tell Turbo to reload your render_async
call as follows:
<%= render_async events_path, html_options: { 'data-turbo-track': 'reload' } %>
This will reload the whole page with Turbo.
:bulb: If Turbo is misbehaving in some way, make sure to put
<%= content_for :render_async %>
in your base view file in the<body>
and not the<head>
.
If you need to restrict the action to only respond to AJAX requests, you'll likely wrap it inside respond_to
/format.js
blocks like this:
def comment_stats
respond_to do |format|
format.js do
@stats = Comment.get_stats
render partial: "comment_stats"
end
end
end
When you do this, Rails will sometimes set the response's Content-Type
header to text/javascript
. This causes the partial not to be rendered in the HTML. This usually happens when there's browser caching.
You can get around it by specifying the content type to text/html
in the render call:
render partial: "comment_stats", content_type: 'text/html'
It is possible to nest async templates within other async templates. When doing so, another content_for
is required to ensure the JavaScript needed to load nested templates is included.
For example:
<%# app/views/comments/show.html.erb %>
<%= render_async comment_stats_path %>
<%# app/views/comments/_comment_stats.html.erb %>
<div class="col-md-6">
<%= @stats %>
</div>
<div class="col-md-6">
<%= render_async comment_advanced_stats_path %>
</div>
<%= content_for :render_async %>
The content_for
name may be customized by passing the content_for_name
option to render_async
. This option is especially useful when doing nested async renders to better control the location of the injected JavaScript.
For example:
<%= render_async comment_stats_path, content_for_name: :render_async_comment_stats %>
<%= content_for :render_async_comment_stats %>
render_async
renders Vanilla JS (regular JavaScript, non-jQuery code) by default in order to fetch the request from the server.
If you want render_async
to use jQuery code, you need to configure it to do so.
You can configure it by doing the following anywhere before you call render_async
:
RenderAsync.configure do |config|
config.jquery = true # This will render jQuery code, and skip Vanilla JS code. The default value is false.
config.turbolinks = true # Enable this option if you are using Turbolinks 5+. The default value is false.
config.turbo = true # Enable this option if you are using Turbo. The default value is false.
config.replace_container = false # Set to false if you want to keep the placeholder div element from render_async. The default value is true.
config.nonces = true # Set to true if you want render_async's javascript_tag always to receive nonce: true. The default value is false.
end
Also, you can do it like this:
# This will render jQuery code, and skip Vanilla JS code
RenderAsync.configuration.jquery = true
Aside from configuring whether the gem relies on jQuery or VanillaJS, you can configure other options:
turbolinks
option - If you are using Turbolinks 5+, you should enable this option since it supports Turbolinks way of loading data. The default value for this option is false.turbo
option - If you are using Turbo, you should enable this option since it supports Turbo way of loading data. The default value for this option is false.replace_container
option - If you want render_async to replace its container with the request response, turn this on. You can turn this on globally for all render_async calls, but if you use this option in a specific render_async call, it will override the global configuration. The default value is true.nonces
- If you need to pass in nonce: true
to the javascript_tag
in your application, it might make sense for you to turn this on globally for all render_async calls. To read more about nonces, check out Rails' official guide on security. The default value is false.After checking out the repo, run bin/setup
to install dependencies. Then, run rake spec
to run the tests. You can also run bin/console
for an interactive prompt that will allow you to experiment. To run integration tests, use bin/integration-tests
. For more information, check out CONTRIBUTING file, please.
Got any questions or comments about development (or anything else)? Join render_async's Discord channel and let's make render_async
even better!
Check out CONTRIBUTING file, please.
Got any issues or difficulties? Join render_async's Discord channel and let's make render_async
even better!
The gem is available as open source under the terms of the MIT License.
Author: renderedtext
Source code: https://github.com/renderedtext/render_async
License: MIT license
1659858780
Infinite scroll displays a limited number of records on the page, new records automatically load when the page scroll reached the bottom of the page. In this tutorial, I show how you can load Postgresql data on page scroll using jQuery, AJAX, and PHP.
Source: https://makitweb.com
1659851460
Cuộn vô hạn hiển thị số lượng bản ghi giới hạn trên trang, các bản ghi mới sẽ tự động tải khi cuộn trang đến cuối trang.
Trong hướng dẫn này, tôi chỉ cách bạn có thể tải dữ liệu Postgresql trên cuộn trang bằng jQuery, AJAX và PHP.
Tôi đang sử dụng posts
bảng trong ví dụ.
CREATE TABLE posts (
id serial PRIMARY KEY,
title varchar(100) NOT NULL,
description text NOT NULL,
link varchar(255) NOT NULL
)
Tạo config.php
tệp cho cấu hình cơ sở dữ liệu.
Mã đã hoàn thành
<?php
$host = "localhost";
$user = "postgres";
$password = "root";
$dbname = "tutorial";
$con = pg_connect("host=$host dbname=$dbname user=$user password=$password");
if (!$con) {
die('Connection failed.');
}
Tôi đặt 3 thành $rowperpage
(Thay đổi giá trị của nó theo số lượng bản ghi bạn muốn hiển thị trên trang cùng một lúc.)
Tìm nạp tổng số bản ghi từ posts
bảng và gán cho $allcount
biến.
Sử dụng $rowperpage
trong giới hạn để tìm nạp các bản ghi. Lặp lại các bản ghi đã tìm nạp và tạo bố cục.
Tạo 3 trường ẩn -
Mã đã hoàn thành
<div class="container">
<?php
include "config.php";
// Row per page
$rowperpage = 3;
// counting total number of posts
$sql = "select count(*) as allcount from posts";
$result = pg_query($con,$sql);
$records = pg_fetch_assoc($result);
$allcount = $records['allcount'];
// select first 3 posts
$sql = "select * from posts order by id asc limit $rowperpage OFFSET 0";
$records = pg_query($con, $sql);
while ($row = pg_fetch_assoc($records)) {
$id = $row['id'];
$title = $row['title'];
$content = $row['description'];
$shortcontent = substr($content, 0, 160)."...";
$link = $row['link'];
?>
<div class="post" id="post_<?php echo $id; ?>">
<h2><?php echo $title; ?></h2>
<p>
<?php echo $shortcontent; ?>
</p>
<a href="<?= $link ?>" target="_blank" class="more">More</a>
</div>
<?php
}
?>
<input type="hidden" id="start" value="0">
<input type="hidden" id="rowperpage" value="<?= $rowperpage ?>">
<input type="hidden" id="totalrecords" value="<?= $allcount ?>">
</div>
Tạo ajaxfile.php
tệp.
Đặt giá trị mặc định $start
thành 0 và $rowperpage
thành 3. Nếu giá trị là POST thì gán giá trị cho các biến.
Tìm nạp bản ghi từ posts
bảng sử dụng POST $rowperpage
và $start
trong LIMIT. Lặp lại các bản ghi đã tìm nạp và tạo bố cục HTML và gán cho $html
biến.
Quay trở lại $html
.
Mã đã hoàn thành
<?php
## Database configuration
include 'config.php';
$start = 0;$rowperpage = 3;
if(isset($_POST['start'])){
$start = $_POST['start'];
}
if(isset($_POST['rowperpage'])){
$rowperpage = $_POST['rowperpage'];
}
## Fetch records
$sql = 'select * from posts order by id desc limit '.$rowperpage.' OFFSET '.$start;
$records = pg_query($con, $sql);
$html = '';
while ($row = pg_fetch_assoc($records)) {
$id = $row['id'];
$title = $row['title'];
$content = $row['description'];
$shortcontent = substr($content, 0, 160)."...";
$link = $row['link'];
// Creating HTML structure
$html .= '<div id="post_'.$id.'" class="post">';
$html .= '<h2>'.$title.'</h2>';
$html .= '<p>'.$shortcontent.'</p>';
$html .= "<a href='".$link."' target='_blank' class='more'>More</a>";
$html .= '</div>';
}
echo $html;
Tạo 2 chức năng -
fetchData()
hàm. Ngoài ra, gọi chức năng này trên trang tải lần đầu tiên để hiển thị nội dung mới nếu trang không có đủ nội dung.Đọc giá trị từ các phần tử ẩn và gán chúng cho các biến. Thêm rowperpage
với start
và kiểm tra xem có không <=
allcount
, nếu đúng thì gửi yêu cầu AJAX POST tới ajaxfile.php
, chuyển start
và rowperpage
dưới dạng dữ liệu.
Khi gọi lại thành công, hãy thêm phản hồi sau class="post"
phần tử cuối cùng và kiểm tra lại kích thước cửa sổ bằng cách gọi checkWindowSize()
.
Xác định 2 sự kiện -
fetchData()
để tìm nạp các bản ghi mới.Mã đã hoàn thành
checkWindowSize();
// Check if the page has enough content or not. If not then fetch records
function checkWindowSize(){
if($(window).height() >= $(document).height()){
// Fetch records
fetchData();
}
}
// Fetch records
function fetchData(){
var start = Number($('#start').val());
var allcount = Number($('#totalrecords').val());
var rowperpage = Number($('#rowperpage').val());
start = start + rowperpage;
if(start <= allcount){
$('#start').val(start);
$.ajax({
url:"ajaxfile.php",
type: 'post',
data: {start:start,rowperpage: rowperpage},
success: function(response){
// Add
$(".post:last").after(response).show().fadeIn("slow");
// Check if the page has enough content or not. If not then fetch records
checkWindowSize();
}
});
}
}
$(document).on('touchmove', onScroll); // for mobile
function onScroll(){
if($(window).scrollTop() > $(document).height() - $(window).height()-100) {
fetchData();
}
}
$(window).scroll(function(){
var position = $(window).scrollTop();
var bottom = $(document).height() - $(window).height();
if( position == bottom ){
fetchData();
}
});
.container{
width: 55%;
margin: 0 auto;
border: 0px solid black;
padding: 10px 0px;
}
/* post */.post{
width: 97%;
min-height: 200px;
padding: 5px;
border: 1px solid gray;
margin-bottom: 15px;
}
.post h2{
letter-spacing: 1px;
font-weight: normal;
font-family: sans-serif;
}
.post p{
letter-spacing: 1px;
text-overflow: ellipsis;
line-height: 25px;
}
/* more link */.more{
color: blue;
text-decoration: none;
letter-spacing: 1px;
font-size: 16px;
}
Điều chỉnh $rowperpage
giá trị theo yêu cầu của bạn. Mã này hoạt động ngay cả khi trang có ít nội dung hơn trong lần tải đầu tiên.
Nguồn: https://makitweb.com
1659844140
Бесконечная прокрутка отображает ограниченное количество записей на странице, новые записи автоматически загружаются, когда прокрутка страницы достигает нижней части страницы.
В этом руководстве я покажу, как вы можете загружать данные Postgresql при прокрутке страницы с помощью jQuery, AJAX и PHP.
Я использую posts
таблицу в примере.
CREATE TABLE posts (
id serial PRIMARY KEY,
title varchar(100) NOT NULL,
description text NOT NULL,
link varchar(255) NOT NULL
)
Создайте config.php
файл для конфигурации базы данных.
Завершенный код
<?php
$host = "localhost";
$user = "postgres";
$password = "root";
$dbname = "tutorial";
$con = pg_connect("host=$host dbname=$dbname user=$user password=$password");
if (!$con) {
die('Connection failed.');
}
Я установил 3 на $rowperpage
(измените его значение в зависимости от того, сколько записей вы хотите отображать на странице одновременно).
Получить общее количество записей из posts
таблицы и присвоить $allcount
переменной.
Используйте $rowperpage
in limit для получения записей. Цикл на извлеченных записях и создание макета.
Создайте 3 скрытых поля –
Завершенный код
<div class="container">
<?php
include "config.php";
// Row per page
$rowperpage = 3;
// counting total number of posts
$sql = "select count(*) as allcount from posts";
$result = pg_query($con,$sql);
$records = pg_fetch_assoc($result);
$allcount = $records['allcount'];
// select first 3 posts
$sql = "select * from posts order by id asc limit $rowperpage OFFSET 0";
$records = pg_query($con, $sql);
while ($row = pg_fetch_assoc($records)) {
$id = $row['id'];
$title = $row['title'];
$content = $row['description'];
$shortcontent = substr($content, 0, 160)."...";
$link = $row['link'];
?>
<div class="post" id="post_<?php echo $id; ?>">
<h2><?php echo $title; ?></h2>
<p>
<?php echo $shortcontent; ?>
</p>
<a href="<?= $link ?>" target="_blank" class="more">More</a>
</div>
<?php
}
?>
<input type="hidden" id="start" value="0">
<input type="hidden" id="rowperpage" value="<?= $rowperpage ?>">
<input type="hidden" id="totalrecords" value="<?= $allcount ?>">
</div>
Создать ajaxfile.php
файл.
Установите значение по умолчанию $start
на 0 и $rowperpage
на 3. Если значения POST, назначьте значения переменным.
Извлекать записи из posts
таблицы, где используется POST $rowperpage
и $start
LIMIT. Зацикливайте на извлеченных записях, создайте HTML-макет и назначьте его $html
переменной.
Вернуться $html
.
Завершенный код
<?php
## Database configuration
include 'config.php';
$start = 0;$rowperpage = 3;
if(isset($_POST['start'])){
$start = $_POST['start'];
}
if(isset($_POST['rowperpage'])){
$rowperpage = $_POST['rowperpage'];
}
## Fetch records
$sql = 'select * from posts order by id desc limit '.$rowperpage.' OFFSET '.$start;
$records = pg_query($con, $sql);
$html = '';
while ($row = pg_fetch_assoc($records)) {
$id = $row['id'];
$title = $row['title'];
$content = $row['description'];
$shortcontent = substr($content, 0, 160)."...";
$link = $row['link'];
// Creating HTML structure
$html .= '<div id="post_'.$id.'" class="post">';
$html .= '<h2>'.$title.'</h2>';
$html .= '<p>'.$shortcontent.'</p>';
$html .= "<a href='".$link."' target='_blank' class='more'>More</a>";
$html .= '</div>';
}
echo $html;
Создайте 2 функции –
fetchData()
функции. Кроме того, вызов этой функции при первой загрузке страницы для отображения нового контента, если на странице недостаточно контента.Считайте значения из скрытых элементов и присвойте их переменным. Добавьте rowperpage
с помощью start
и проверьте, если это так <=
allcount
, если это так, отправьте запрос AJAX POST на ajaxfile.php
, передайте start
и rowperpage
как данные.
При успешном обратном вызове добавьте ответ после последнего class="post"
элемента и снова проверьте размер окна, вызвав checkWindowSize()
.
Определить 2 события –
fetchData()
, чтобы получить новые записи.Завершенный код
checkWindowSize();
// Check if the page has enough content or not. If not then fetch records
function checkWindowSize(){
if($(window).height() >= $(document).height()){
// Fetch records
fetchData();
}
}
// Fetch records
function fetchData(){
var start = Number($('#start').val());
var allcount = Number($('#totalrecords').val());
var rowperpage = Number($('#rowperpage').val());
start = start + rowperpage;
if(start <= allcount){
$('#start').val(start);
$.ajax({
url:"ajaxfile.php",
type: 'post',
data: {start:start,rowperpage: rowperpage},
success: function(response){
// Add
$(".post:last").after(response).show().fadeIn("slow");
// Check if the page has enough content or not. If not then fetch records
checkWindowSize();
}
});
}
}
$(document).on('touchmove', onScroll); // for mobile
function onScroll(){
if($(window).scrollTop() > $(document).height() - $(window).height()-100) {
fetchData();
}
}
$(window).scroll(function(){
var position = $(window).scrollTop();
var bottom = $(document).height() - $(window).height();
if( position == bottom ){
fetchData();
}
});
.container{
width: 55%;
margin: 0 auto;
border: 0px solid black;
padding: 10px 0px;
}
/* post */.post{
width: 97%;
min-height: 200px;
padding: 5px;
border: 1px solid gray;
margin-bottom: 15px;
}
.post h2{
letter-spacing: 1px;
font-weight: normal;
font-family: sans-serif;
}
.post p{
letter-spacing: 1px;
text-overflow: ellipsis;
line-height: 25px;
}
/* more link */.more{
color: blue;
text-decoration: none;
letter-spacing: 1px;
font-size: 16px;
}
Отрегулируйте $rowperpage
значение в соответствии с вашими требованиями. Этот код работает, даже если на странице меньше контента при первой загрузке.
Источник: https://makitweb.com
1659836580
無限滾動在頁面上顯示有限數量的記錄,當頁面滾動到頁面底部時會自動加載新記錄。
在本教程中,我將展示如何使用 jQuery、AJAX 和 PHP 在頁面滾動上加載 Postgresql 數據。
我正在使用posts
示例中的表格。
CREATE TABLE posts (
id serial PRIMARY KEY,
title varchar(100) NOT NULL,
description text NOT NULL,
link varchar(255) NOT NULL
)
為數據庫配置創建config.php
文件。
完成的代碼
<?php
$host = "localhost";
$user = "postgres";
$password = "root";
$dbname = "tutorial";
$con = pg_connect("host=$host dbname=$dbname user=$user password=$password");
if (!$con) {
die('Connection failed.');
}
我將 3 設置為$rowperpage
(根據您希望一次在頁面上顯示的記錄數更改其值。)
從表中獲取記錄總數posts
並分配給$allcount
變量。
在 limit 中使用$rowperpage
來獲取記錄。循環獲取的記錄並創建佈局。
創建 3 個隱藏字段 –
完成的代碼
<div class="container">
<?php
include "config.php";
// Row per page
$rowperpage = 3;
// counting total number of posts
$sql = "select count(*) as allcount from posts";
$result = pg_query($con,$sql);
$records = pg_fetch_assoc($result);
$allcount = $records['allcount'];
// select first 3 posts
$sql = "select * from posts order by id asc limit $rowperpage OFFSET 0";
$records = pg_query($con, $sql);
while ($row = pg_fetch_assoc($records)) {
$id = $row['id'];
$title = $row['title'];
$content = $row['description'];
$shortcontent = substr($content, 0, 160)."...";
$link = $row['link'];
?>
<div class="post" id="post_<?php echo $id; ?>">
<h2><?php echo $title; ?></h2>
<p>
<?php echo $shortcontent; ?>
</p>
<a href="<?= $link ?>" target="_blank" class="more">More</a>
</div>
<?php
}
?>
<input type="hidden" id="start" value="0">
<input type="hidden" id="rowperpage" value="<?= $rowperpage ?>">
<input type="hidden" id="totalrecords" value="<?= $allcount ?>">
</div>
創建ajaxfile.php
文件。
將默認值設置$start
為 0 和$rowperpage
3。如果值為 POST,則將值分配給變量。
posts
從使用 POST$rowperpage
和$start
LIMIT的表中獲取記錄。循環獲取的記錄並創建 HTML 佈局並分配給$html
變量。
返回$html
。
完成的代碼
<?php
## Database configuration
include 'config.php';
$start = 0;$rowperpage = 3;
if(isset($_POST['start'])){
$start = $_POST['start'];
}
if(isset($_POST['rowperpage'])){
$rowperpage = $_POST['rowperpage'];
}
## Fetch records
$sql = 'select * from posts order by id desc limit '.$rowperpage.' OFFSET '.$start;
$records = pg_query($con, $sql);
$html = '';
while ($row = pg_fetch_assoc($records)) {
$id = $row['id'];
$title = $row['title'];
$content = $row['description'];
$shortcontent = substr($content, 0, 160)."...";
$link = $row['link'];
// Creating HTML structure
$html .= '<div id="post_'.$id.'" class="post">';
$html .= '<h2>'.$title.'</h2>';
$html .= '<p>'.$shortcontent.'</p>';
$html .= "<a href='".$link."' target='_blank' class='more'>More</a>";
$html .= '</div>';
}
echo $html;
創建 2 個函數 –
fetchData()
函數加載新內容。此外,如果頁面沒有足夠的內容,則在頁面第一次加載時調用此函數以顯示新內容。從隱藏元素中讀取值並將它們分配給變量。添加rowperpage
withstart
並檢查是否是<=
allcount
,如果是則發送 AJAX POST 請求到ajaxfile.php
,傳遞start
和rowperpage
作為數據。
在回調成功後,在最後一個元素之後添加響應,class="post"
並通過調用再次檢查窗口大小checkWindowSize()
。
定義 2 個事件 –
fetchData()
以獲取新記錄。完成的代碼
checkWindowSize();
// Check if the page has enough content or not. If not then fetch records
function checkWindowSize(){
if($(window).height() >= $(document).height()){
// Fetch records
fetchData();
}
}
// Fetch records
function fetchData(){
var start = Number($('#start').val());
var allcount = Number($('#totalrecords').val());
var rowperpage = Number($('#rowperpage').val());
start = start + rowperpage;
if(start <= allcount){
$('#start').val(start);
$.ajax({
url:"ajaxfile.php",
type: 'post',
data: {start:start,rowperpage: rowperpage},
success: function(response){
// Add
$(".post:last").after(response).show().fadeIn("slow");
// Check if the page has enough content or not. If not then fetch records
checkWindowSize();
}
});
}
}
$(document).on('touchmove', onScroll); // for mobile
function onScroll(){
if($(window).scrollTop() > $(document).height() - $(window).height()-100) {
fetchData();
}
}
$(window).scroll(function(){
var position = $(window).scrollTop();
var bottom = $(document).height() - $(window).height();
if( position == bottom ){
fetchData();
}
});
.container{
width: 55%;
margin: 0 auto;
border: 0px solid black;
padding: 10px 0px;
}
/* post */.post{
width: 97%;
min-height: 200px;
padding: 5px;
border: 1px solid gray;
margin-bottom: 15px;
}
.post h2{
letter-spacing: 1px;
font-weight: normal;
font-family: sans-serif;
}
.post p{
letter-spacing: 1px;
text-overflow: ellipsis;
line-height: 25px;
}
/* more link */.more{
color: blue;
text-decoration: none;
letter-spacing: 1px;
font-size: 16px;
}
$rowperpage
根據您的要求調整值。即使頁面在第一次加載時內容較少,此代碼也有效。
1659829320
Le défilement infini affiche un nombre limité d'enregistrements sur la page, les nouveaux enregistrements se chargent automatiquement lorsque le défilement de la page atteint le bas de la page.
Dans ce didacticiel, je montre comment vous pouvez charger des données Postgresql lors du défilement d'une page à l'aide de jQuery, AJAX et PHP.
J'utilise posts
le tableau de l'exemple.
CREATE TABLE posts (
id serial PRIMARY KEY,
title varchar(100) NOT NULL,
description text NOT NULL,
link varchar(255) NOT NULL
)
Créer config.php
un fichier pour la configuration de la base de données.
Code terminé
<?php
$host = "localhost";
$user = "postgres";
$password = "root";
$dbname = "tutorial";
$con = pg_connect("host=$host dbname=$dbname user=$user password=$password");
if (!$con) {
die('Connection failed.');
}
J'ai défini 3 sur $rowperpage
(modifiez sa valeur en fonction du nombre d'enregistrements que vous souhaitez afficher sur la page à la fois.)
Récupérer le nombre total d'enregistrements de la posts
table et l'affecter à la $allcount
variable.
Utiliser $rowperpage
dans la limite pour récupérer des enregistrements. Bouclez sur les enregistrements récupérés et créez une mise en page.
Créez 3 champs masqués –
Code terminé
<div class="container">
<?php
include "config.php";
// Row per page
$rowperpage = 3;
// counting total number of posts
$sql = "select count(*) as allcount from posts";
$result = pg_query($con,$sql);
$records = pg_fetch_assoc($result);
$allcount = $records['allcount'];
// select first 3 posts
$sql = "select * from posts order by id asc limit $rowperpage OFFSET 0";
$records = pg_query($con, $sql);
while ($row = pg_fetch_assoc($records)) {
$id = $row['id'];
$title = $row['title'];
$content = $row['description'];
$shortcontent = substr($content, 0, 160)."...";
$link = $row['link'];
?>
<div class="post" id="post_<?php echo $id; ?>">
<h2><?php echo $title; ?></h2>
<p>
<?php echo $shortcontent; ?>
</p>
<a href="<?= $link ?>" target="_blank" class="more">More</a>
</div>
<?php
}
?>
<input type="hidden" id="start" value="0">
<input type="hidden" id="rowperpage" value="<?= $rowperpage ?>">
<input type="hidden" id="totalrecords" value="<?= $allcount ?>">
</div>
Créer ajaxfile.php
un fichier.
Définissez la valeur par défaut de $start
sur 0 et $rowperpage
sur 3. Si les valeurs sont POST, affectez les valeurs aux variables.
Récupérer les enregistrements de posts
la table où utiliser POST $rowperpage
et $start
dans LIMIT. Bouclez sur les enregistrements récupérés et créez une mise en page HTML et attribuez-la à la $html
variable.
Retour $html
.
Code terminé
<?php
## Database configuration
include 'config.php';
$start = 0;$rowperpage = 3;
if(isset($_POST['start'])){
$start = $_POST['start'];
}
if(isset($_POST['rowperpage'])){
$rowperpage = $_POST['rowperpage'];
}
## Fetch records
$sql = 'select * from posts order by id desc limit '.$rowperpage.' OFFSET '.$start;
$records = pg_query($con, $sql);
$html = '';
while ($row = pg_fetch_assoc($records)) {
$id = $row['id'];
$title = $row['title'];
$content = $row['description'];
$shortcontent = substr($content, 0, 160)."...";
$link = $row['link'];
// Creating HTML structure
$html .= '<div id="post_'.$id.'" class="post">';
$html .= '<h2>'.$title.'</h2>';
$html .= '<p>'.$shortcontent.'</p>';
$html .= "<a href='".$link."' target='_blank' class='more'>More</a>";
$html .= '</div>';
}
echo $html;
Créer 2 fonctions –
fetchData()
la fonction. De plus, appeler cette fonction lors du premier chargement de la page pour afficher un nouveau contenu si la page n'a pas assez de contenu.Lire les valeurs des éléments masqués et les affecter aux variables. Ajoutez rowperpage
avec start
et vérifiez si c'est le <=
allcount
cas, si c'est le cas, envoyez ensuite la requête AJAX POST à ajaxfile.php
, passez start
et rowperpage
en tant que données.
En cas de rappel réussi, ajoutez une réponse après le dernier class="post"
élément et vérifiez à nouveau la taille de la fenêtre en appelant checkWindowSize()
.
Définir 2 événements –
fetchData()
pour récupérer de nouveaux enregistrements.Code terminé
checkWindowSize();
// Check if the page has enough content or not. If not then fetch records
function checkWindowSize(){
if($(window).height() >= $(document).height()){
// Fetch records
fetchData();
}
}
// Fetch records
function fetchData(){
var start = Number($('#start').val());
var allcount = Number($('#totalrecords').val());
var rowperpage = Number($('#rowperpage').val());
start = start + rowperpage;
if(start <= allcount){
$('#start').val(start);
$.ajax({
url:"ajaxfile.php",
type: 'post',
data: {start:start,rowperpage: rowperpage},
success: function(response){
// Add
$(".post:last").after(response).show().fadeIn("slow");
// Check if the page has enough content or not. If not then fetch records
checkWindowSize();
}
});
}
}
$(document).on('touchmove', onScroll); // for mobile
function onScroll(){
if($(window).scrollTop() > $(document).height() - $(window).height()-100) {
fetchData();
}
}
$(window).scroll(function(){
var position = $(window).scrollTop();
var bottom = $(document).height() - $(window).height();
if( position == bottom ){
fetchData();
}
});
.container{
width: 55%;
margin: 0 auto;
border: 0px solid black;
padding: 10px 0px;
}
/* post */.post{
width: 97%;
min-height: 200px;
padding: 5px;
border: 1px solid gray;
margin-bottom: 15px;
}
.post h2{
letter-spacing: 1px;
font-weight: normal;
font-family: sans-serif;
}
.post p{
letter-spacing: 1px;
text-overflow: ellipsis;
line-height: 25px;
}
/* more link */.more{
color: blue;
text-decoration: none;
letter-spacing: 1px;
font-size: 16px;
}
Ajustez $rowperpage
la valeur en fonction de vos besoins. Ce code fonctionne même si la page a moins de contenu lors du premier chargement.
Source : https://makitweb.com
1659821820
El desplazamiento infinito muestra un número limitado de registros en la página, los nuevos registros se cargan automáticamente cuando el desplazamiento de la página llega al final de la página.
En este tutorial, muestro cómo puede cargar datos de Postgresql en el desplazamiento de la página usando jQuery, AJAX y PHP.
Estoy usando posts
la tabla en el ejemplo.
CREATE TABLE posts (
id serial PRIMARY KEY,
title varchar(100) NOT NULL,
description text NOT NULL,
link varchar(255) NOT NULL
)
Crear config.php
archivo para la configuración de la base de datos.
Código completado
<?php
$host = "localhost";
$user = "postgres";
$password = "root";
$dbname = "tutorial";
$con = pg_connect("host=$host dbname=$dbname user=$user password=$password");
if (!$con) {
die('Connection failed.');
}
Establecí 3 en $rowperpage
(cambie su valor según la cantidad de registros que desee mostrar en la página a la vez).
Obtenga el número total de registros de posts
la tabla y asígnelos a la $allcount
variable.
Use $rowperpage
in limit para obtener registros. Haga un bucle en los registros obtenidos y cree un diseño.
Crea 3 campos ocultos –
Código completado
<div class="container">
<?php
include "config.php";
// Row per page
$rowperpage = 3;
// counting total number of posts
$sql = "select count(*) as allcount from posts";
$result = pg_query($con,$sql);
$records = pg_fetch_assoc($result);
$allcount = $records['allcount'];
// select first 3 posts
$sql = "select * from posts order by id asc limit $rowperpage OFFSET 0";
$records = pg_query($con, $sql);
while ($row = pg_fetch_assoc($records)) {
$id = $row['id'];
$title = $row['title'];
$content = $row['description'];
$shortcontent = substr($content, 0, 160)."...";
$link = $row['link'];
?>
<div class="post" id="post_<?php echo $id; ?>">
<h2><?php echo $title; ?></h2>
<p>
<?php echo $shortcontent; ?>
</p>
<a href="<?= $link ?>" target="_blank" class="more">More</a>
</div>
<?php
}
?>
<input type="hidden" id="start" value="0">
<input type="hidden" id="rowperpage" value="<?= $rowperpage ?>">
<input type="hidden" id="totalrecords" value="<?= $allcount ?>">
</div>
Crear ajaxfile.php
archivo.
Establezca el valor predeterminado de $start
0 y $rowperpage
3. Si los valores son POST, asigne los valores a las variables.
Obtenga registros de posts
la tabla donde use POST $rowperpage
y $start
en LIMIT. Haga un bucle en los registros obtenidos y cree un diseño HTML y asigne a la $html
variable.
Volver $html
_
Código completado
<?php
## Database configuration
include 'config.php';
$start = 0;$rowperpage = 3;
if(isset($_POST['start'])){
$start = $_POST['start'];
}
if(isset($_POST['rowperpage'])){
$rowperpage = $_POST['rowperpage'];
}
## Fetch records
$sql = 'select * from posts order by id desc limit '.$rowperpage.' OFFSET '.$start;
$records = pg_query($con, $sql);
$html = '';
while ($row = pg_fetch_assoc($records)) {
$id = $row['id'];
$title = $row['title'];
$content = $row['description'];
$shortcontent = substr($content, 0, 160)."...";
$link = $row['link'];
// Creating HTML structure
$html .= '<div id="post_'.$id.'" class="post">';
$html .= '<h2>'.$title.'</h2>';
$html .= '<p>'.$shortcontent.'</p>';
$html .= "<a href='".$link."' target='_blank' class='more'>More</a>";
$html .= '</div>';
}
echo $html;
Crear 2 funciones –
fetchData()
la función. Además, llamar a esta función en la página que se carga por primera vez para mostrar contenido nuevo si la página no tiene suficiente contenido.Leer valores de elementos ocultos y asignarlos a las variables. Agregue rowperpage
con start
y verifique si es <=
allcount
, si es así, envíe la solicitud AJAX POST a ajaxfile.php
, pase start
y rowperpage
como datos.
En una devolución de llamada exitosa, agregue la respuesta después del último class="post"
elemento y verifique nuevamente el tamaño de la ventana llamando a checkWindowSize()
.
Definir 2 eventos –
fetchData()
para obtener nuevos registros.Código completado
checkWindowSize();
// Check if the page has enough content or not. If not then fetch records
function checkWindowSize(){
if($(window).height() >= $(document).height()){
// Fetch records
fetchData();
}
}
// Fetch records
function fetchData(){
var start = Number($('#start').val());
var allcount = Number($('#totalrecords').val());
var rowperpage = Number($('#rowperpage').val());
start = start + rowperpage;
if(start <= allcount){
$('#start').val(start);
$.ajax({
url:"ajaxfile.php",
type: 'post',
data: {start:start,rowperpage: rowperpage},
success: function(response){
// Add
$(".post:last").after(response).show().fadeIn("slow");
// Check if the page has enough content or not. If not then fetch records
checkWindowSize();
}
});
}
}
$(document).on('touchmove', onScroll); // for mobile
function onScroll(){
if($(window).scrollTop() > $(document).height() - $(window).height()-100) {
fetchData();
}
}
$(window).scroll(function(){
var position = $(window).scrollTop();
var bottom = $(document).height() - $(window).height();
if( position == bottom ){
fetchData();
}
});
.container{
width: 55%;
margin: 0 auto;
border: 0px solid black;
padding: 10px 0px;
}
/* post */.post{
width: 97%;
min-height: 200px;
padding: 5px;
border: 1px solid gray;
margin-bottom: 15px;
}
.post h2{
letter-spacing: 1px;
font-weight: normal;
font-family: sans-serif;
}
.post p{
letter-spacing: 1px;
text-overflow: ellipsis;
line-height: 25px;
}
/* more link */.more{
color: blue;
text-decoration: none;
letter-spacing: 1px;
font-size: 16px;
}
Ajuste $rowperpage
el valor según sus requisitos. Este código funciona incluso si la página tiene menos contenido la primera vez que se carga.
Fuente: https://makitweb.com
1659818700
Plugin DataTables là cách dễ nhất để thêm phân trang trên trang với tất cả các tính năng cần thiết.
Để thêm điều khiển xóa, bạn có thể thêm nút xóa với mỗi bản ghi hoặc thêm hộp kiểm và một nút xóa duy nhất.
Trong hướng dẫn này, tôi chỉ cách bạn thêm nhiều hộp kiểm và xóa các bản ghi đã chọn chỉ bằng một cú nhấp chuột trong DataTables bằng cách sử dụng jQuery AJAX.
Tạo employee
bảng.
CREATE TABLE `employee` (
`id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
`emp_name` varchar(60) NOT NULL,
`salary` varchar(50) NOT NULL,
`gender` varchar(10) NOT NULL,
`city` varchar(80) NOT NULL,
`email` varchar(80) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Tạo config.php
kết nối cơ sở dữ liệu.
Mã đã hoàn thành
<?php
$host = "localhost"; /* Host name */$user = "root"; /* User */$password = ""; /* Password */$dbname = "tutorial"; /* Database name */
$con = mysqli_connect($host, $user, $password,$dbname);
// Check connection
if (!$con) {
die("Connection failed: " . mysqli_connect_error());
}
datatables.min.css
và datatables.min.js
trong <head>
phần và cũng bao gồm Thư viện jQuery.<!-- Datatable CSS -->
<link href='//cdn.datatables.net/1.10.19/css/jquery.dataTables.min.css' rel='stylesheet' type='text/css'>
<!-- jQuery Library -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!-- Datatable JS -->
<script src="//cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js"></script>
Tạo một <table id='empTable' class='display dataTable' >
.
Thêm hàng tiêu đề.
Trong ô cuối cùng, thêm hộp kiểm kiểm tra tất cả và một nút để xóa các bản ghi đã kiểm tra.
Mã đã hoàn thành
<div >
<!-- Table -->
<table id='empTable' class='display dataTable'>
<thead>
<tr>
<th>Employee name</th>
<th>Email</th>
<th>Gender</th>
<th>Salary</th>
<th>City</th>
<th>Check All <input type="checkbox" class='checkall' id='checkall'><input type="button" id='delete_record' value='Delete' ></th>
</tr>
</thead>
</table>
</div>
Khởi tạo DataTable -
Khởi tạo DataTable trên <table id='empTable' >
.
Thêm 'processing': true
,. 'serverSide': true
_ 'serverMethod': 'post'
_ Chỉ định url AJAX và 'ajax'
tùy chọn sử dụng dữ liệu.
Sử dụng 'columns'
tùy chọn để chỉ định tên trường cần được đọc từ phản hồi AJAX.
Loại bỏ sắp xếp từ cột cuối cùng bằng cách sử dụng columnDefs
tùy chọn.
Rà soát tất cả -
Nếu hộp kiểm checkall được nhấp vào thì hãy kiểm tra xem nó có được chọn hay không. Nếu được chọn, hãy đặt tất cả các hộp kiểm được chọn class='delete_check'
.
Nếu không được chọn, hãy xóa đã chọn khỏi tất cả các hộp kiểm.
Đã chọn hộp kiểm -
Tạo một checkcheckbox()
chức năng.
Đếm tổng số hộp kiểm và hộp kiểm đã chọn có class='delete_check'
trên trang.
Nếu tổng số hộp kiểm bằng tổng số hộp kiểm đã chọn thì hãy chọn hộp kiểm tổng số hộp kiểm, nếu không hãy bỏ chọn hộp kiểm.
Nút xóa -
Đọc tất cả các hộp kiểm đã chọn theo class='delete_check'
và đẩy giá trị trong deleteids_arr
Mảng.
Nếu deleteids_arr
độ dài mảng lớn hơn thì hiển thị cảnh báo xác nhận. Gửi yêu cầu AJAX POST tới 'ajaxfile.php' để xóa các bản ghi khi ok
nút được nhấp.
Vượt qua request: 2
, deleteids_arr: deleteids_arr
như data
.
Khi gọi lại thành công, hãy tải lại Datatable bằng cách gọi dataTable.ajax.reload()
.
Mã đã hoàn thành
var dataTable;
$(document).ready(function(){
// Initialize datatable
dataTable = $('#empTable').DataTable({
'processing': true,
'serverSide': true,
'serverMethod': 'post',
'ajax': {
'url':'ajaxfile.php',
'data': function(data){
data.request = 1;
}
},
'columns': [
{ data: 'emp_name' },
{ data: 'email' },
{ data: 'gender' },
{ data: 'salary' },
{ data: 'city' },
{ data: 'action' },
],
'columnDefs': [ {
'targets': [5], // column index (start from 0)
'orderable': false, // set orderable false for selected columns
}]
});
// Check all
$('#checkall').click(function(){
if($(this).is(':checked')){
$('.delete_check').prop('checked', true);
}else{
$('.delete_check').prop('checked', false);
}
});
// Delete record
$('#delete_record').click(function(){
var deleteids_arr = [];
// Read all checked checkboxes
$("input:checkbox[class=delete_check]:checked").each(function () {
deleteids_arr.push($(this).val());
});
// Check checkbox checked or not
if(deleteids_arr.length > 0){
// Confirm alert
var confirmdelete = confirm("Do you really want to Delete records?");
if (confirmdelete == true) {
$.ajax({
url: 'ajaxfile.php',
type: 'post',
data: {request: 2,deleteids_arr: deleteids_arr},
success: function(response){
dataTable.ajax.reload();
}
});
}
}
});
});
// Checkbox checked
function checkcheckbox(){
// Total checkboxes
var length = $('.delete_check').length;
// Total checked checkboxes
var totalchecked = 0;
$('.delete_check').each(function(){
if($(this).is(':checked')){
totalchecked+=1;
}
});
// Checked unchecked checkbox
if(totalchecked == length){
$("#checkall").prop('checked', true);
}else{
$('#checkall').prop('checked', false);
}
}
Tạo một ajaxfile.php
tệp.
Từ tệp này, xử lý hai yêu cầu AJAX -
$request == 1
sau đó đọc giá trị DataTables POST. Nếu $searchQuery
không trống thì hãy chuẩn bị truy vấn tìm kiếm. Đếm tổng số bản ghi không có và có bộ lọc.Tìm nạp các bản ghi từ employee
bảng trong đó chỉ định truy vấn tìm kiếm, sắp xếp theo và giới hạn.
Lặp lại các bản ghi đã tìm nạp và khởi tạo $data
Mảng với các khóa được chỉ định trong columns
tùy chọn trong khi khởi tạo DataTable.
Gán hộp kiểm trong ‘action’
khóa. Trong hộp kiểm đã thêm onclick=‘checkcheckbox()’
, hãy chuyển $row[‘id’]
thuộc value
tính và class=‘delete_check’
.
Gán các khóa bắt buộc với các giá trị trong $response
Mảng và trả về ở định dạng JSON.
$request == 2
sau đó lặp lại trên $deleteids_arr
Mảng và thực hiện DELETE
truy vấn trên id.Mã đã hoàn thành
<?php
include 'config.php';
$request = $_POST['request'];
// Datatable data
if($request == 1){
## Read value
$draw = $_POST['draw'];
$row = $_POST['start'];
$rowperpage = $_POST['length']; // Rows display per page
$columnIndex = $_POST['order'][0]['column']; // Column index
$columnName = $_POST['columns'][$columnIndex]['data']; // Column name
$columnSortOrder = $_POST['order'][0]['dir']; // asc or desc
$searchValue = mysqli_real_escape_string($con,$_POST['search']['value']); // Search value
## Search
$searchQuery = " ";
if($searchValue != ''){
$searchQuery .= " and (emp_name like '%".$searchValue."%' or
email like '%".$searchValue."%' or
city like'%".$searchValue."%' ) ";
}
## Total number of records without filtering
$sel = mysqli_query($con,"select count(*) as allcount from employee");
$records = mysqli_fetch_assoc($sel);
$totalRecords = $records['allcount'];
## Total number of records with filtering
$sel = mysqli_query($con,"select count(*) as allcount from employee WHERE 1 ".$searchQuery);
$records = mysqli_fetch_assoc($sel);
$totalRecordwithFilter = $records['allcount'];
## Fetch records
$empQuery = "select * from employee WHERE 1 ".$searchQuery." order by ".$columnName." ".$columnSortOrder." limit ".$row.",".$rowperpage;
$empRecords = mysqli_query($con, $empQuery);
$data = array();
while ($row = mysqli_fetch_assoc($empRecords)) {
$data[] = array(
"emp_name"=>$row['emp_name'],
"email"=>$row['email'],
"gender"=>$row['gender'],
"salary"=>$row['salary'],
"city"=>$row['city'],
"action"=>"<input type='checkbox' class='delete_check' id='delcheck_".$row['id']."' onclick='checkcheckbox();' value='".$row['id']."'>"
);
}
## Response
$response = array(
"draw" => intval($draw),
"iTotalRecords" => $totalRecords,
"iTotalDisplayRecords" => $totalRecordwithFilter,
"aaData" => $data
);
echo json_encode($response);
exit;
}
// Delete record
if($request == 2){
$deleteids_arr = array();
if(isset($_POST['deleteids_arr'])){
$deleteids_arr = $_POST['deleteids_arr'];
}
foreach($deleteids_arr as $deleteid){
mysqli_query($con,"DELETE FROM employee WHERE id=".$deleteid);
}
echo 1;
exit;
}
Tạo một cột riêng để thêm hộp kiểm với các bản ghi.
Trên vòng lặp nhấp vào nút xóa trên các hộp kiểm đã chọn và gửi yêu cầu AJAX để XÓA nó và làm mới DataTable.
Nguồn: https://makitweb.com