目录
1. XMLHttpRequest Level2的新特性——FormData对象管理表单数据(一)
用法(二)
2. XMLHttpRequest Level2的新特性—— 上传文件
3. XMLHttpRequest Level2的新特性—— 显示文件上传进度
4. jQuery高级用法
4.1 jQuery实现文件上传
4.2 jQuery实现loading效果
5. axios
5.1 什么是axios
5.2 axios发起GET请求
5.3 axios发起POST请求编辑
5.4 直接使用axios发起请求
6. 了解同源策略和跨域
6.1 同源策略
6.2 跨域
7. JSONP
7.1 什么是JSONP
7.2 JSONP的实现原理
7.3 自己实现一个简单的JSONP
7.4 JSONP的缺点
7.5 jQuery中的JSONP
7.6 自定义参数及回调函数名称
7.7 jQuery中JSONP的实现过程
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请求
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包裹)