Ajax第五篇:JQuery中使用Ajax
第一章:常用API
1.1-ajax方法使用格式
$.ajax({
// 请求地址
url: 'http://localhost/find',
// 请求方式
type: 'POST',
// 一对“文件名-文件值”在本机设置XHR对象。例如,如果需要的话,你可以用它来设置withCredentials为true的跨域请求。
xhrFields: {widthCredentials:true},
// 请求发送之前的处理函数
beforeSend: function(){},
// 响应成功后的处理函数
success: function(response){},
// 异常处理函数
error: function(ex){},
// 请求参数 可以是“key=value&key=value”、{key:value,key:value}、FormData对象
data: formData,
// 是否缓存
cache: false,
// 发送给服务器的编码类型,默认application/x-www-form-urlencoded
contentType: 'application/x-www-form-urlencoded',
// JSONP跨域
dataType: 'JSONP',
// (默认: true) 默认情况下,通过data选项传递进来的数据,如果是一个对象(技术上讲只要不是字符串),都会处理转化成一个查询字符串,以配合默认内容类型 "application/x-www-form-urlencoded"。如果要发送 DOM 树信息或其它不希望转换的信息,请设置为 false。
processData: false
});
1.2-get和post方法
作用:$.get
方法用于发送get请求,$.post
方法用于发送post请求。
$.get('http://www.example.com', {name: 'zhangsan', age: 30}, function (response) {}) $.post('http://www.example.com', {name: 'lisi', age: 22}, function (response) {})
1.2-案例-登录
服务端程序
const express = require('express')
const path = require('path')
const bodyParser = require('body-parser')
const app = express();
app.use(express.static(path.join(__dirname, './public')))
app.use(bodyParser.urlencoded({ extend: false }))
// 登录接口
app.post('/login', (req, res) => {
const user = req.body;
if (user.name == 'admin' && user.pwd == '111') {
res.send('登录成功')
} else {
res.send('账号或密码错误')
}
})
app.listen(80, "localhost")
前端程序
<p>账号:<input type="text" id="userDom"></p>
<p>密码:<input type="password" id="pwdDom"></p>
<p><button id="btn">登录</button></p>
<script src="./lib/jquery.js"></script>
<script>
btn.onclick = function() {
$.ajax({
type: 'post',
url: 'login',
data: {name:userDom.value, pwd:pwdDom.value},
success:function(response){
alert(response)
},
error: function(e) {
console.log(e)
}
})
}
</script>
1.3-案例-账号唯一验证
服务端程序
const express = require('express')
const path = require('path')
const app = express();
app.use(express.static(path.join(__dirname, './public')))
// 账号唯一验证接口
app.get('/check', (req, res) => {
if (req.query.user=='admin') {
res.send('该用户名已经存在,请更换')
} else {
res.send('可以使用')
}
})
app.listen(80, "localhost")
前端程序
<p>账号:<input type="text" id="userDom"></p>
<script src="./lib/jquery.js"></script>
<script>
userDom.onblur = function() {
$.ajax({
url: 'check',
data: {user:userDom.value},
success:function(response){
console.log(response)
},
error: function(e) {
console.log(e)
}
})
}
</script>
1.4-案例-文件上传
后端程序
const express = require('express')
const path = require('path')
const app = express();
const formidable = require('formidable')
app.use(express.static(path.join(__dirname, './public')))
// 文件上传接口
app.post('/upload', (req, res) => {
// 创建formidable对象
const form = new formidable.IncomingForm();
// 保留上传文件的后缀名
form.keepExtensions = true;
// 设置上传文件大小最大限制
form.maxFileSize = 2 * 1024 * 1024 * 1024;
// 设置文件保存路径
form.uploadDir = path.join(__dirname, './public/upload');
// 解析表单
form.parse(req, (err, fields, files) => {
res.send(files.photo.path.split('public\\')[1])
})
})
app.listen(80, "localhost")
前端程序
<input type="file" id="photos"><br>
<div style="width: 500px; border:1px solid #ccc; height: 5px; border-radius: 5px;display: inline-block;">
<!-- 上传进度条 -->
<div id="processDom" style="margin: 0; width: 0%; background: deepskyblue; height: 100%; border-radius: 5px;"></div>
</div>上传进度<strong id="processNum">0%</strong>
<p id="preview">
</p>
<script src="./lib/jquery.js"></script>
<script>
photos.onchange = function () {
console.log(photos.files)
if (photos.files.length != 0) {
// 创建FormData对象
var fromData = new FormData();
// 将文件数据追加表单中
fromData.append('photo', photos.files[0])
// 发送ajax请求
$.ajax({
type: 'post',
url: 'upload',
contentType: false, // 不设置内容类型
processData: false, // 不序列化参数
xhr: function () {
// 获取原生的XMLHttpRequest对象
var xhr = $.ajaxSettings.xhr()
if (xhr.upload) {
xhr.upload.addEventListener("progress", function (e) {
// 计算上传进度百分比
var num = (e.loaded / e.total) * 100;
// 设置进度条
processDom.style.width = num + '%';
// 更新进度数值
processNum.innerText = parseInt(num) + '%'
})
}
return xhr; // 一定要返回
},
data: fromData,
success: function (response) {
var img = document.createElement('img');
img.src = response;
img.style.width="100px";
preview.append(img)
},
error: function (e) {
console.log(e)
}
})
}
}
</script>
第二章:全局方法
2.1-ajax相关全局事件
概述
只要页面中有Ajax请求被发送,对应的全局事件就会被触发
- ajaxStart(callback) 当请求开始发送时触发
- ajaxComplete(callback) AJAX 请求完成时执行函数。Ajax 事件。
对于ajax相关的全局事件,事件源设置给document
第三方插件介绍:NProgress纳米进度条
- NProgress.start(); // 进度条开始运动
- NProgress.done(); // 进度条结束运动
代码演示
<p>账号:<input type="text" id="userDom"></p>
<p>密码:<input type="password" id="pwdDom"></p>
<p><button id="btn">登录</button></p>
<link rel="stylesheet" href="./lib/nprogress.css">
<script src="./lib/jquery.js"></script>
<script src="./lib/nprogress.js"></script>
<script>
btn.onclick = function () {
$.ajax({
type: 'post',
url: 'login',
data: { name: userDom.value, pwd: pwdDom.value },
success: function (response) {
console.log(response)
},
error: function (e) {
console.log(e)
}
})
}
// ajax开始发送请求
$(document).on('ajaxStart', function () {
console.log('开始')
NProgress.start();
})
// ajax响应完毕
$(document).on('ajaxComplete', function () {
NProgress.done();
console.log('结束')
})
</script>
2.2-表单序列化方法
- serialize() 序列表表格内容为字符串,用于 Ajax 请求。
- 格式:
name=value&navme=value
- 格式:
- serializeArray() 序列化表格元素 (类似 '.serialize()' 方法) 返回 JSON 数据结构数据。
- 格式:
[{name: 'firstname', value: 'Hello'}]
- 格式:
<form id="info">
<p>用户名:<input type="text" name="username"></p>
<p>密码:<input type="password" name="pwd"></p>
<p>验证码:<input type="text" name="code"></p>
</form>
<button id="btn">注册</button>
<script src="./lib/jquery.js"></script>
<script>
btn.onclick= function(){
console.log($('#info').serialize())
// username=admin&pwd=123456&code=00Cn2f
var arr = $('#info').serializeArray();
console.log(arr)
// [{name:'username',value:'admin'}, {…}, {…}]
// 将[{name:'username',value:'admin'}, {…}, {…}]转换为 {key:value,key:value}
var obj = {};
for(var i = 0; i < arr.length; i++) {
var item = arr[i];
obj[item.name] = item.value;
}
console.log(obj)
// {username: "admin", pwd: "123456", code: "00Cn2f"}
}
</script>
第三章:RESTful API
要弄清楚什么是RESTful API,首先要知道REST是什么。
REST,表示性状态转移(representation state transfer)。简单来说,就是用
URI
表示资源,用HTTP方法(GET, POST, PUT, DELETE)表征对这些资源的操作。
- Resource: 资源,即数据,存在互联网上的可被访问的实体
- Representation: 数据的某种表现形式,如HTML, JSON。
- State Transfer:状态变化,HTTP方法实现
RESTful API 就是REST风格的API。现在终端平台多样,移动、平板、PC等许多媒介向服务端发送请求后,如果不适用RESTful API,需要为每个平台的数据请求定义相应的返回格式,以适应前端显示。但是RESTful API 要求前端以一种预定义的语法格式发送请求,那么服务端就只需要定义一个统一的响应接口,不必像之前那样解析各色各式的请求。
RESTful 是典型的基于HTTP的协议。它有哪些设计原则和规范呢?
-
资源。首先要明确资源就是网络上的一个实体,可以是文本、图片、音频、视频。资源总是以一定的格式来表现自己。文本用txt、html;图片用JPG、JPEG等等。而JSON是RESTful API中最常用的资源表现格式。
-
统一接口。对于业务数据的CRUD,RESTful 用HTTP方法与之对应。
-
URI。统一资源标识符,它可以唯一标识一个资源。注意到,URL(统一资源定位符)是一种URI,因为它可以唯一标志资源。但URL != URI。应该说URL 是URI的子集。因为URL使用路径来唯一标识资源,这只是唯一标识资源的一种方式。还可以用一个唯一编号来标识资源,如example.html.fuce2da23。只不过这种方式并不被广泛使用。总之,要在概念上对URL和URI有所区分。
-
无状态。 所谓无状态是指所有资源都可以用URI定位,而且这个定位与其他资源无关,不会因为其他资源的变动而变化。这里引入一个幂等性的概念:无论一个操作被执行一次还是多次,执行后的效果都相同。比如对某资源发送GET请求,如果访问一次和访问十次获得的数据一样,那么就说这个请求具有幂等性。
-
URL中只能有名词,不能出现动词。这是因为在REST要求对资源的操作由HTTP 方法给出,而方法是由HTTP 请求报文头部给出的,自然不需要在URL中暴露操作方式。
还有一些属于业务决定型规则,比如应该将版本加到URL中,对返回记录进行限制过滤。不是强制的,但是比较建议这么做。
代码演示
后端程序
const express = require('express')
const path = require('path')
const bodyParser = require('body-parser')
const app = express();
app.use(express.static(path.join(__dirname, './public')))
app.use(bodyParser.urlencoded({ extend: false }))
// http://localhost/user
app.get('/user', (req, res) => {
res.send('get-查找所有用户')
})
// http://localhost/user/1
app.get('/user/:id', (req, res) => {
res.send(`get-查找id为${req.params.id}用户`)
})
// http://localhost/user
app.post('/user', (req, res) => {
res.send(`post-添加用户`)
})
// http://localhost/user/1
app.delete('/user/:id', (req, res) => {
res.send(`delete-删除id为${req.params.id}用户`)
})
// http://localhost/user/1
app.put('/user/:id', (req, res) => {
res.send(`put-修改id为${req.params.id}用户`)
})
app.listen(80, "localhost")
前端程序
<button id="btn1">get1</button>
<button id="btn2">get2</button>
<button id="btn3">post</button>
<button id="btn4">delete</button>
<button id="btn5">put</button>
<script src="./jquery.js"></script>
<script>
// 查找所有用户
btn1.onclick = function () {
$.ajax({
url: 'http://localhost/user',
type: 'get',
success: function (response) {
console.log(response)
}
})
}
// 查找id为1用户
btn2.onclick = function () {
$.ajax({
url: 'http://localhost/user/1',
type: 'get',
success: function (response) {
console.log(response)
}
})
}
// 添加用户
btn3.onclick = function () {
$.ajax({
url: 'http://localhost/user',
type: 'post',
success: function (response) {
console.log(response)
}
})
}
// 删除id为2的用户
btn4.onclick = function () {
$.ajax({
url: 'http://localhost/user/2',
type: 'delete',
success: function (response) {
console.log(response)
}
})
}
// 修改id为1的用户
btn5.onclick = function () {
$.ajax({
url: 'http://localhost/user/1',
type: 'put',
success: function (response) {
console.log(response)
}
})
}
</script>