目录
1. XMLHttpRequest Level2的新特性——FormData对象管理表单数据(一)
2. XMLHttpRequest Level2的新特性—— 上传文件
3. XMLHttpRequest Level2的新特性—— 显示文件上传进度
1. XMLHttpRequest Level2的新特性——FormData对象管理表单数据(一)
除了html里面用form标签
<script>
// 1. 创建 FormData 实例
var fd = new FormData()
// 2. 调用 append 函数,向 fd 中追加数据
fd.append('uname', 'zs')
fd.append('upwd', '123456')
var xhr = new XMLHttpRequest()
xhr.open('POST', 'http://www.liulongbin.top:3006/api/formdata')
xhr.send(fd)
//把提交的数据传过来
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
//服务器响应回来的文本格式的Json字符串转成js对象打印出来
console.log(JSON.parse(xhr.responseText))
}
}
</script>
用法(二)
<body>
<form id="form1">
<input type="text" name="uname" autocomplete="off" />
<input type="password" name="upwd" />
<button type="submit">提交</button>
</form>
<script>
// 1. 通过 DOM 操作,获取到 form 表单元素
var form = document.querySelector('#form1')
// 监听表单元素的 submit 事件
form.addEventListener('submit', function (e) {
// 阻止表单的默认提交行为
e.preventDefault()
// 创建 FormData,快速获取到 form 表单中的数据到fd
var fd = new FormData(form)
//发ajax请求
var xhr = new XMLHttpRequest()
xhr.open('POST', 'http://www.liulongbin.top:3006/api/formdata')
xhr.send(fd)
//拿到服务器响应回来的数据
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
console.log(JSON.parse(xhr.responseText))
}
}
})
</script>
</body>
2. XMLHttpRequest Level2的新特性—— 上传文件
以上完整代码:
<body>
<!-- 1. 文件选择框 -->
<input type="file" id="file1" />
<!-- 2. 上传文件的按钮 -->
<button id="btnUpload">上传文件</button>
<br />
<!-- 3. img 标签,来显示上传成功以后的图片 -->
<img src="" alt="" id="img" width="800" />
<script>
// 1. 获取到文件上传按钮
var btnUpload = document.querySelector('#btnUpload')
// 2. 为按钮绑定单击事件处理函数
btnUpload.addEventListener('click', function () {
// 3. 获取到用户选择的文件列表 files数组里面拿到用户选择的文件
//document.querySelector('#file1')拿到文件选择框的dom元素.files是一个文件的数组
var files = document.querySelector('#file1').files
//files是个数组
if (files.length <= 0) {
return alert('请选择要上传的文件!')
}
//向FormData中追加文件
var fd = new FormData()
// 将用户选择的文件,添加到 FormData 中
fd.append('avatar', files[0])
var xhr = new XMLHttpRequest()
xhr.open('POST', 'http://www.liulongbin.top:3006/api/upload/avatar')
xhr.send(fd)
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
var data = JSON.parse(xhr.responseText)
if (data.status === 200) {
//querySelector选择器
// 上传成功,将上传成功的图片再显示到网页中(将服务器响应回来的url地址交给img标签进行显示)
//data.url地址(服务器响应回来的url地址)不完整,需要在前面拼上一个根路径
document.querySelector('#img').src = 'http://www.liulongbin.top:3006' + data.url
} else {
// 上传失败,打印一个上传文件失败的消息就行
console.log('图片上传失败!' + data.message)
}
}
}
})
</script>
</body>
3. XMLHttpRequest Level2的新特性—— 显示文件上传进度
e. lengthComputable为true时,才能计算出上传进度
e.loaded / e.total) * 100 上传进度百分比
Math.ceil上取整
美化文件上传进度:Bootstrap中文网组件里找进度条
完整上传及美化代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<link rel="stylesheet" href="./lib/bootstrap.css" />
<script src="./lib/jquery.js"></script>
</head>
<body>
<!-- 1. 文件选择框 -->
<input type="file" id="file1" />
<!-- 2. 上传文件的按钮 -->
<button id="btnUpload">上传文件</button>
<!-- bootstrap 中的进度条(Bootstrap中文网组件里复制过来的) -->
<!-- style="width: 500px; margin: 15px 10px控制进度条的样式 -->
<div class="progress" style="width: 500px; margin: 15px 10px;">
<!-- style="width: 0%"进度条的增长效果从这改 -->
<div class="progress-bar progress-bar-striped active" style="width: 0%" id="percent">
0%
<!-- 0%这块改变的是当前显示的数据 -->
</div>
</div>
<br />
<!-- 3. img 标签,来显示上传成功以后的图片 -->
<img src="" alt="" id="img" width="800" />
<script>
// 1. 获取到文件上传按钮
var btnUpload = document.querySelector('#btnUpload')
// 2. 为按钮绑定单击事件处理函数
btnUpload.addEventListener('click', function () {
// 3. 获取到用户选择的文件列表
var files = document.querySelector('#file1').files
if (files.length <= 0) {
return alert('请选择要上传的文件!')
}
var fd = new FormData()
// 将用户选择的文件,添加到 FormData 中
fd.append('avatar', files[0])
var xhr = new XMLHttpRequest()
//新加的比12
// 监听文件上传的进度
xhr.upload.onprogress = function (e) {
if (e.lengthComputable) {
// e.lengthComputable为true,可以计算出上传的进度
var procentComplete = Math.ceil((e.loaded / e.total) * 100)
//在Network里选择slow3G网络上传
console.log(procentsComplete)
// 动态设置进度条
//jOuery的dom操作: $('#percent')获取到进度条,.attr函数设置进度条的style属性,动态设置width宽度
//.html()函数显示当前的上传进度百分比
$('#percent').attr('style', 'width: ' + procentComplete + '%;').html(procentComplete + '%')
}
}
// 监听上传完成的事件 .removeClass()移除样式 .addClass添加样式绿色
xhr.upload.onload = function () {
$('#percent').removeClass().addClass('progress-bar progress-bar-success')
}
xhr.open('POST', 'http://www.liulongbin.tSop:3006/api/upload/avatar')
xhr.send(fd)
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
var data = JSON.parse(xhr.responseText)
if (data.status === 200) {
// 上传成功
document.querySelector('#img').src = 'http://www.liulongbin.top:3006' + data.url
} else {
// 上传失败
console.log('图片上传失败!' + data.message)
}
}
}
})
</script>
</body>
</html>
4. jQuery高级用法
4.1 jQuery实现文件上传
用jQuery发起上传文件的请求:contentType/processData必须: false
必须调用$.ajax请求 method必须是post
4.2 jQuery实现loading效果
jQuery高级用法完整代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script src="./lib/jquery.js"></script>
</head>
<body>
<input type="file" id="file1" />
<button id="btnUpload">上传文件</button>
<br />
<!-- style="display: none先把图片隐藏起来,设置id:loading -->
<img src="./images/loading.gif" alt="" style="display: none;" id="loading" />
<script>
$(function () {
// 监听到Ajax请求被发起了
$(document).ajaxStart(function () {
$('#loading').show()
})
// 监听到 Ajax 完成的事件
$(document).ajaxStop(function () {
$('#loading').hide()
})
$('#btnUpload').on('click', function () {
//[0]转成原生的dom对象
var files = $('#file1')[0].files
if (files.length <= 0) {
return alert('请选择文件后再上传!')
}
var fd = new FormData()
fd.append('avatar', files[0])
// 发起 jQuery 的 Ajax 请求,上传文件
$.ajax({
method: 'POST',
url: 'http://www.liulongbin.top:3006/api/upload/avatar',
data: fd,
processData: false,
contentType: false,
success: function (res) {
console.log(res)
}
})
})
})
</script>
</body>
</html>
5. axios
5.1 什么是axios
5.2 axios发起GET请求
.then指定成功以后的回调函数
包装的res对象身上始终都有6个属性,要的是data(服务器响应回来的真实数据)
5.3 axios发起POST请求![](https://img-blog.csdnimg.cn/7160e6c1b6f34e01b504acd1445f0c5c.png)
5.4 直接使用axios发起请求
axios测试完整代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script src="./lib/axios.js"></script>
</head>
<body>
<button id="btn1">发起GET请求</button>
<button id="btn2">发起POST请求</button>
<button id="btn3">直接使用axios发起GET请求</button>
<button id="btn4">直接使用axios发起POST请求</button>
<script>
document.querySelector('#btn1').addEventListener('click', function () {
var url = 'http://www.liulongbin.top:3006/api/get'
var paramsObj = { name: 'zs', age: 20 }
axios.get(url, { params: paramsObj }).then(function (res) {
//res是axios包装的一个对象,要的是data(服务器响应回来的真实数据)
console.log(res.data)
})
})
document.querySelector('#btn2').addEventListener('click', function () {
var url = 'http://www.liulongbin.top:3006/api/post'
var dataObj = { address: '北京', location: '顺义区' }
axios.post(url, dataObj).then(function (res) {
console.log(res.data)
})
})
document.querySelector('#btn3').addEventListener('click', function () {
var url = 'http://www.liulongbin.top:3006/api/get'
var paramsData = { name: '钢铁侠', age: 35 }
axios({
method: 'GET',
url: url,
params: paramsData
}).then(function (res) {
console.log(res.data)
})
})
document.querySelector('#btn4').addEventListener('click', function () {
axios({
method: 'POST',
url: 'http://www.liulongbin.top:3006/api/post',
data: {
name: '娃哈哈',
age: 18,
gender: '女'
}
}).then(function (res) {
console.log(res.data)
})
})
</script>
</body>
</html>
6. 了解同源策略和跨域
6.1 同源策略
http://www.test.com/后面要是没给数据的话,默认80
同源策略:浏览器提供的,保证安全性(隔离潜在恶意文件)
通俗的理解:浏览器规定,A 网站的 JavaScript,不允许和非同源的网站 C 之间,进行资源的交互
6.2 跨域
URL 的协议、域名、端口三个完全一致叫同源;任何一个不一致叫跨域
注意:请求回来的数据会被浏览器的同源策略拦截
7. JSONP
7.1 什么是JSONP
7.2 JSONP的实现原理
发起跨域的Ajax请求的报错测试:请求失败,拿不到数据
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script src="./lib/jquery.js"></script>
</head>
<!-- 浏览器拦截,console里面报错,打开的网页是file协议,接口的协议是http
非同源,存在跨域问题-->
<body>
<script>
$.ajax({
method: 'GET',
url: 'http://ajax.frontend.itheima.net:3006/api/jsonp',
data: {
name: 'zs',
age: 20
},
success: function (res) {
console.log(res)
}
})
</script>
</body>
</html>
7.3 自己实现一个简单的JSONP
<!-- 剖析JSONP的实现原理1 -->
<!-- 把函数的定义和调用拆成了两部分 -->
<body>
<script>
function success(data) {
console.log('拿到了Data数据:')
console.log(data)
}
</script>
<script>
success({ name: 'zs', age: 20 })
</script>
</body>
<!-- 剖析JSONP的实现原理2 -->
<body>
<script>
function abc(data) {
console.log('拿到了Data数据:')
console.log(data)
}
</script>
<!-- src请求外部的js文件 -->
<script src="./js/getdata.js?callback=abc"></script>
</body>
// getdata.js文件
abc({ name: 'ls', age: 30 })
//简单的JSONP请求实现
<!-- JSONP不是Ajax请求,是Get请求 -->
<!-- getdata.js没有在计算机本地上,而是在一台服务器上放着,人家调什么函数我们不知道 -->
<body>
<script>
function abc(data) {
console.log('JSONP响应回来的数据是:')
console.log(data)
}
</script>
<!-- 设置回调函数callback=abc,让服务器知道客户端只有abc这一个函数 -->
<script src="http://ajax.frontend.itheima.net:3006/api/jsonp?callback=abc&name=ls&age=30"></script>
</body>
7.4 JSONP的缺点
JSONP默认发起js脚本请求,<script>标签默认发起get请求,没有post请求
7.5 jQuery中的JSONP
?name=zs&age=20是我们希望通过JSONP发送给服务器的数据
7.6 自定义参数及回调函数名称
改参数直接在jsonp:“把callback改成你想要的”
7.7 jQuery中JSONP的实现过程
<body>
<button id="btnJSONP">发起JSONP数据请求</button>
<script>
// $(function ()jQuery的入口函数
$(function () {
$('#btnJSONP').on('click', function () {
$.ajax({
url: 'http://ajax.frontend.itheima.net:3006/api/jsonp?address=北京&location=顺义',
dataType: 'jsonp',
jsonpCallback: 'abc',
success: function (res) {
console.log(res)
}
})
})
})
</script>
</body>
在浏览器中检查head标签中动态新增script标签(点击的时候),前提在Network中把网速降到Slow 3G,把url动态显示在head里面(由script包裹)