静态资源和Ajax请求

本文介绍在Django项目中使用静态资源,需创建保存目录并修改配置文件,此配置仅用于开发测试。还阐述了Ajax技术,可实现页面局部刷新,且JSON数据格式更优。最后用Ajax实现投票功能,修改URL映射、设计视图函数、引入jQuery库,后续将添加登录注册功能。

(留存备忘,转自author:骆昊)

加载静态资源

如果要在Django项目中使用静态资源,可以先创建一个用于保存静态资源的目录。在vote项目中,我们将静态资源置于名为static的文件夹中,在该文件夹包含了三个子文件夹:css、js和images,分别用来保存外部CSS文件、外部JavaScript文件和图片资源,如下图所示。

 

为了能够找到保存静态资源的文件夹,我们还需要修改Django项目的配置文件settings.py,如下所示:

STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static'), ]
STATIC_URL = '/static/'

配置好静态资源之后,大家可以运行项目,然后看看之前我们写的页面上的图片是否能够正常加载出来。需要说明的是,在项目正式部署到线上环境后,我们通常会把静态资源交给专门的静态资源服务器(如Nginx、Apache)来处理,而不是有运行Python代码的服务器来管理静态资源,所以上面的配置并不适用于生产环境,仅供项目开发阶段测试使用。使用静态资源的正确姿势我们会在后续的章节为大家讲解。

Ajax概述

接下来就可以实现“好评”和“差评”的功能了,很明显如果能够在不刷新页面的情况下实现这两个功能会带来更好的用户体验,因此我们考虑使用[Ajax](https://zh.wikipedia.org/wiki/AJAX)技术来实现“好评”和“差评”。Ajax是Asynchronous Javascript And XML的缩写 , 简单的说,使用Ajax技术可以在不重新加载整个页面的情况下对页面进行局部刷新。

对于传统的Web应用,每次页面上需要加载新的内容都需要重新请求服务器并刷新整个页面,如果服务器短时间内无法给予响应或者网络状况并不理想,那么可能会造成浏览器长时间的空白并使得用户处于等待状态,在这个期间用户什么都做不了,如下图所示。很显然,这样的Web应用并不能带来很好的用户体验。

 

对于使用Ajax技术的Web应用,浏览器可以向服务器发起异步请求来获取数据。异步请求不会中断用户体验,当服务器返回了新的数据,我们可以通过JavaScript代码进行DOM操作来实现对页面的局部刷新,这样就相当于在不刷新整个页面的情况下更新了页面的内容,如下图所示。

 

在使用Ajax技术时,浏览器跟服务器通常会交换XML或JSON格式的数据,XML是以前使用得非常多的一种数据格式,近年来几乎已经完全被JSON取代,下面是两种数据格式的对比。

XML格式:

<?xml version="1.0" encoding="utf-8"?>
<message>
	<from>Alice</from>
    <to>Bob</to>
    <content>Dinner is on me!</content>
</message>

JSON格式:

{
    "from": "Alice",
    "to": "Bob",
    "content": "Dinner is on me!"
}

通过上面的对比,明显JSON格式的数据要紧凑得多,所以传输效率更高,而且JSON本身也是JavaScript中的一种对象表达式语法,在JavaScript代码中处理JSON格式的数据更加方便。

用Ajax实现投票功能

下面,我们使用Ajax技术来实现投票的功能,首先修改项目的urls.py文件,为“好评”和“差评”功能映射对应的URL。

from django.contrib import admin
from django.urls import path

from vote import views

urlpatterns = [
    path('', views.show_subjects),
    path('teachers/', views.show_teachers),
    path('praise/', views.prise_or_criticize),
    path('criticize/', views.prise_or_criticize),
    path('admin/', admin.site.urls),
]

设计视图函数praise_or_criticize来支持“好评”和“差评”功能,该视图函数通过Django封装的JsonResponse类将字典序列化成JSON字符串作为返回给浏览器的响应内容。

def praise_or_criticize(request):
    """好评"""
    try:
        tno = int(request.GET.get('tno'))
        teacher = Teacher.objects.get(no=tno)
        if request.path.startswith('/praise'):
            teacher.good_count += 1
            count = teacher.good_count
        else:
            teacher.bad_count += 1
            count = teacher.bad_count
        teacher.save()
        data = {'code': 20000, 'mesg': '操作成功', 'count': count}
    except (ValueError, Teacher.DoseNotExist):
        data = {'code': 20001, 'mesg': '操作失败'}
    return JsonResponse(data)

修改显示老师信息的模板页,引入jQuery库来实现事件处理、Ajax请求和DOM操作。

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>老师信息</title> <style> #container { width: 80%; margin: 10px auto; } .teacher { width: 100%; margin: 0 auto; padding: 10px 0; border-bottom: 1px dashed gray; overflow: auto; } .teacher>div { float: left; } .photo { height: 140px; border-radius: 75px; overflow: hidden; margin-left: 20px; } .info { width: 75%; margin-left: 30px; } .info div { clear: both; margin: 5px 10px; } .info span { margin-right: 25px; } .info a { text-decoration: none; color: darkcyan; } </style> </head> <body> <div id="container"> <h1>{{ subject.name }}学科的老师信息</h1> <hr> {% if not teachers %} <h2>暂无该学科老师信息</h2> {% endif %} {% for teacher in teachers %} <div class="teacher"> <div class="photo"> <img src="/static/images/{{ teacher.photo }}" height="140" alt=""> </div> <div class="info"> <div> <span><strong>姓名:{{ teacher.name }}</strong></span> <span>性别:{{ teacher.sex | yesno:'男,女' }}</span> <span>出生日期:{{ teacher.birth }}</span> </div> <div class="intro">{{ teacher.intro }}</div> <div class="comment"> <a href="/praise/?tno={{ teacher.no }}">好评</a>?? (<strong>{{ teacher.good_count }}</strong>) ???? <a href="/criticize/?tno={{ teacher.no }}">差评</a>?? (<strong>{{ teacher.bad_count }}</strong>) </div> </div> </div> {% endfor %} <a href="/">返回首页</a> </div> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> <script> $(() => { $('.comment>a').on('click', (evt) => { evt.preventDefault() let url = $(evt.target).attr('href') $.getJSON(url, (json) => { if (json.code == 20000) { $(evt.target).next().text(json.count) } else { alert(json.mesg) } }) }) }) </script> </body> </html> 

上面的前端代码中,使用了jQuery库封装的getJSON方法向服务器发送异步请求,如果不熟悉前端的jQuery库,可以参考[《jQuery API手册》](https://www.runoob.com/manual/jquery/)。

小结

到此为止,这个投票项目的核心功能已然完成,在下面的章节中我们会要求用户必须登录才能投票,没有账号的用户可以通过注册功能注册一个账号。

<think>嗯,用户问的是Src请求Ajax请求之间的区别。首先,我需要明确这两个术语的具体含义,因为有时候可能会有不同的解释。首先,Src请求可能指的是通过HTML标签的src属性发起的请求,比如<img>、<script>、<iframe>等标签。这些标签的src属性会触发浏览器自动下载指定资源,属于传统的资源加载方式。而Ajax请求则是通过JavaScript发起的异步HTTP请求,可以在不刷新页面的情况下与服务器交换数据。接下来,我需要整理两者的区别。从加载方式来看,Src请求是浏览器自动发起的,属于同步加载,可能会阻塞页面渲染;而Ajax请求是异步的,不会阻塞页面。然后,应用场景方面,Src请求通常用于静态资源,如图片、脚本等,而Ajax用于动态数据交互,如表单提交、实时更新等。数据格式方面,Src请求一般返回的是资源文件,而Ajax可以处理多种数据格式,如JSON、XML等。还有控制权,Src由浏览器控制,开发者只能设置URL,而Ajax允许开发者自定义请求头、方法等。另外,安全性方面,Ajax受到同源策略限制,而Src请求在某些标签(如<img>)中可以跨域,但像<script>的跨域请求可能需要JSONP。性能方面,Ajax可以按需加载,减少带宽消耗,而Src请求可能一次性加载所有资源,影响性能。还要考虑历史背景,Ajax的出现是为了解决传统同步请求的体验问题,比如页面刷新。而Src请求是早期HTML就存在的机制。同时,现代Web开发中,Ajax被Fetch API进一步优化,解决了回调地狱的问题。需要确保回答结构清晰,分点列出区别,并结合引用中的相关内容。例如,引用提到Ajax的异步请求导致回调地狱,后来有了Fetch,这可能XHR与Fetch的区别有关,但用户问题主要在于SrcAjax的区别。引用中关于Ajax局部更新、不重新加载页面的例子,可以用于说明Ajax的应用场景,而Src请求如百度搜索的联想数据可能实际是Ajax的例子,需要确认。可能用户混淆了某些概念,比如Src请求是否包括XHR,但根据常见用法,Src是标签属性发起的,而Ajax是JS发起的。需要明确区分两者的技术实现,并举例说明。最后,生成相关问题,帮助用户深入理解,比如应用场景、性能对比、安全性等。</think>### Src请求Ajax请求的区别详解 #### 1. **定义与用途** - **Src请求**:通过HTML标签的`src`属性触发(如`<img>`、`<script>`、`<iframe>`),主要用于加载静态资源(图片、脚本、框架等)。浏览器自动发起请求,**无需开发者编写额外代码**。 - 示例:`<script src="app.js"></script>`[^4] - **Ajax请求**:通过JavaScript的`XMLHttpRequest`或`fetch` API实现,用于**异步获取动态数据**(如用户输入、实时更新)。需手动编写请求逻辑,**不阻塞页面渲染**。 - 示例:通过输入关键词触发搜索联想数据[^3]。 #### 2. **加载方式** - **Src请求**: - **同步加载**:默认阻塞页面渲染(如`<script>`标签未加`async`/`defer`属性时)。 - **资源类型固定**:返回内容由标签类型决定(如`<img>`仅接收图像数据)。 - **Ajax请求**: - **异步加载**:后台发送请求,不干扰用户操作(如提交表单时不刷新页面)[^3]。 - **数据格式灵活**:支持JSON、XML、文本等,可通过代码解析[^5]。 #### 3. **控制粒度** - **Src请求**: - **控制权有限**:开发者只能设置URL,无法自定义请求头或方法(如强制GET请求)。 - **无进度监控**:浏览器自动处理加载过程,无法实时追踪进度。 - **Ajax请求**: - **完全控制**:可自定义请求头(如`Content-Type`)、方法(GET/POST/PUT等)及超时时间[^2][^5]。 - **支持进度监控**:通过事件监听上传/下载进度(如`fetch`结合`ReadableStream`)[^5]。 #### 4. **安全性** - **Src请求**: - **跨域限制宽松**:部分标签允许跨域(如`<img>`),但`<script>`需依赖JSONP或CORS。 - **Ajax请求**: - **同源策略严格**:默认禁止跨域请求,需通过CORS或代理解决[^4]。 #### 5. **性能与场景** - **Src请求**: - **适用场景**:静态资源预加载(如页面初始化时加载核心脚本)。 - **性能缺陷**:一次性加载可能浪费带宽(如未用懒加载的图片)。 - **Ajax请求**: - **适用场景**:动态内容按需加载(如分页数据、实时搜索)[^3]。 - **性能优势**:减少冗余数据传输,提升页面响应速度[^1]。 --- ### 对比表格 | 特性 | Src请求 | Ajax请求 | |-------------------|----------------------------|-----------------------------| | **触发方式** | HTML标签属性 | JavaScript API | | **数据交互** | 单向(仅获取资源) | 双向(可发送/接收数据) | | **请求控制** | 浏览器自动处理 | 开发者手动控制 | | **局部更新** | 不支持(需刷新页面) | 支持(仅更新指定区域)[^3] | | **历史兼容性** | 所有浏览器原生支持 | 需兼容XHR或fetch API[^1][^5]| --- ### 代码示例 **Ajax请求(XHR实现)**: ```javascript const xhr = new XMLHttpRequest(); xhr.open('GET', '/api/data'); xhr.onload = () => { if (xhr.status === 200) console.log(xhr.response); }; xhr.send(); ``` **Fetch API(现代替代方案)**: ```javascript fetch('/api/data') .then(response => response.json()) .then(data => console.log(data)); ``` ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Alocus_

如果我的内容帮助到你,打赏我吧

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值