前后端交互(四)——Ajax(一)

目录

一.Ajax编程基础

1.Ajax 基本介绍

2.Ajax 实现步骤

3.服务器端响应的数据格式

4.请求参数传递

4.1 GET请求参数传递

4.2 POST请求参数传递

5.获取服务器端的响应

6.Ajax 错误处理

7.低版本 IE浏览器的缓存问题

8.Ajax 封装

二.客户端模板引擎

1.验证邮箱地址唯一性

2.搜索框内容自动提示

3.省市区三级联动

三.FormData

1.模拟 HTML表单

2.异步上传二进制文件


一.Ajax编程基础

1.Ajax 基本介绍

  • 传统网站存在的问题:
  1. 网速慢,页面加载时间长,用户只能等待  
  2. 表单提交后,如果一项内容不合格,需要重新填写所有表单内容  
  3. 页面跳转,重新加载页面,造成资源浪费,增加用户等待时间
  • Ajax:实现页面无刷新更新数据,提高用户浏览网站应用的体验
  • Ajax 应用场景:
  1. 页面上拉加载更多数据
  2. 表单项离开焦点数据验证
  3. 搜索框提示文字下拉列表
  • Ajax 运行环境:需要运行在网站环境中才能生效,比如:Node创建的 网站服务器
  • Ajax 运行原理:相当于浏览器 发送请求 与 接收响应 的代理人:

2.Ajax 实现步骤

var xhr = new XMLHttpRequest();                 // 1.创建ajax对象
xhr.open('get', 'http://localhost:3000/first'); // 2.告诉 Ajax对象: 1)请求方式 2)请求地址
xhr.send();                                     // 3.发送请求
xhr.onload = function (){                       // 4.获取 服务器端响应到客户端的 数据
	console.log(xhr.responseText)}              // xhr.responseText 是JSON字符串格式

3.服务器端响应的数据格式

  • 服务器端大多数情况会以  JSON对象 作为 响应数据 的格式
  • 客户端拿到响应数据时,要将 JSON数据 和 HTML字符串 进行拼接,将拼接结果展示在页面中
  • 在 HTTP 请求与响应的过程中,请求参数、响应内容 如果是对象类型,都会被转换为 对象字符串 传输
  • JSON.parse():将 json字符串 转换为 json对象
  • JSON.stringify():将 json对象 转换为 json字符串
// .html文件
xhr.onload = function (){                         // 获取服务器端响应到客户端的数据
var responseText = JSON.parse(xhr.responseText);  // 将 JSON字符串 转换为 JSON对象
var str = '<h2>'+ responseText.name +'</h2>';     // 将数据和html字符串进行拼接
document.body.innerHTML = str;}                   // 将拼接的结果追加到页面中
// app.js文件
app.get('/responseData', (req, res) => {
	res.send({"name": "zs"}); // 传入的是 json对象格式,HTTP会自动换成 json字符串格式
});

4.请求参数传递

  • 传统网站表单提交:

4.1 GET请求参数传递

// .html文件
<p><input type="text" id="username"></p>
<p><input type="text" id="age"></p>
<p><input type="button" value="提交" id="btn"></p>
<script type="text/javascript">
		var btn = document.getElementById('btn');             // 获取按钮元素
		var username = document.getElementById('username');   // 获取姓名文本框
		var age = document.getElementById('age');             // 获取年龄文本框
		btn.onclick = function () {                           // 为按钮添加点击事件
			var nameValue = username.value;                   // 获取用户在文本框中输入的值
			var ageValue = age.value;
			var params = 'username='+ nameValue +'&age=' + ageValue; // 拼接请求参数
			var xhr = new XMLHttpRequest();                          // 创建ajax对象
			xhr.open('get', 'http://localhost:3000/get?'+params);    // 配置ajax对象
			xhr.send();                                        // 发送请求
			xhr.onload = function () {                         // 获取服务器端响应的数据
				console.log(xhr.responseText)
			}}</script>
// app.js文件
app.get('/get', (req, res) => {
	res.send(req.query);
});
  • 注意:get 不能提交 json对象数据格式,传统网站的表单提交也不支持 json对象数据格式
  • GET请求参数传递是在 配置ajax对象的时候 传递的:xhr.open('get', 'http://localhost:3000/get?'+params);

4.2 POST请求参数传递

// .html文件
var xhr = new XMLHttpRequest();                 // 创建ajax对象
xhr.open('post', 'http://localhost:3000/post'); // 配置ajax对象
                           // 设置请求参数格式的类型(post请求必须要设置)
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.send(JSON.stringify({name: 'lisi', age:50})); // 发送请求,post在发送请求时 传递参数
xhr.onload = function () { // 获取服务器端响应的数据
    console.log(xhr.responseText)}
// app.js文件
app.post('/post', (req, res) => {
	res.send(req.body);
});
  • 请求头:设置请求参数格式的类型(post请求必须写):xhr.setRequestHeader('Content-Type', '......');
  • 通过 请求头 告诉服务器端,客户端向服务器端传递的 请求参数的格式 是什么
  1. application/x-www-form-urlencoded:    name=Lyrelion&age=20  向服务器传送 字符串格式 的请求参数
  2. application/json:    {name:'zs',age:'20'}  向服务器传送 json对象格式 的请求参数 send(转为json字符串)
  • POST请求参数传递是在 发送ajax请求的时候 传递的:xhr.send(params);
  • 请求报文:HTTP 请求响应传递的 数据块,包括:请求方式、请求地址、要传送的数据、一些附加信息
  • 客户端  →    →  服务器端

5.获取服务器端的响应

  • Ajax状态码:创建ajax对象,配置ajax对象,发送请求,接收完服务器端响应数据,每个步骤对应的数值
  1. 0:请求未初始化,创建了 ajax对象,没有调用open()
  2. 1:请求已经建立,还没有发送,调用了open(),没有调用send()
  3. 2:请求已经发送,xhr.onreadystatechange = function()......
  4. 3:请求正在处理中,通常响应中已经有 部分数据 可以用了
  5. 4:响应已经完成,可以获取并使用服务器的响应数据了
  • 获取 HTTP状态码:xhr.status
  • 获取 Ajax状态码:xhr.readyState
  • onreadystatechange事件:Ajax状态码 发生变化时,将自动触发该事件
  • 在事件处理函数中,Ajax状态码为 4 时,就可以通过 xhr.responseText 获取服务器端的响应数据了
// .html文件
var xhr = new XMLHttpRequest();                      // 0:创建ajax对象 还没进行配置
xhr.open('get', 'http://localhost:3000/readystate'); // 1:配置ajax对象 还没发送请求
xhr.onreadystatechange = function() {                // ajax状态码 发生变化 
			// 2:请求已经发送了
			// 3:已经接收到服务器端的部分数据了
			// 4:服务器端的响应数据已经接收完成
	 if (xhr.readyState == 4) {                  // 判断 Ajax状态码 为 4 时
             console.log(xhr.responseText); }}       // 获取服务器端的响应数据
         xhr.send(); 
// app.js文件
app.get('/readystate', (req, res) => {
	res.send('hello');
});
  • 推荐使用 onload事件,仅调用一次,且不需要判断状态码,提高了效率
  • 当需要考虑兼容 低版本IE浏览器时,推荐使用 onreadystatechange事件

6.Ajax 错误处理

  1. 网络畅通,服务器端能接收到请求,但返回的结果不是预期结果:判断服务器端返回的状态码,分别进行处理
  2. 网络畅通,服务器端没有接收到请求,返回404状态码:检查 请求地址是否错误
  3. 网络畅通,服务器端能接收到请求,返回500状态码:服务器端错误,如服务器端有不存在的变量名,找后端程序员
  4. 网络中断,请求无法发送到服务器端,会触发 xhr.onerror事件,在 onerror事件处理函数中对错误进行处理
  • Ajax状态码:表示 Ajax请求的过程状态,ajax对象返回的
  • Http状态码:表示请求的处理结果,服务器端返回的
// .html文件
        var btn = document.getElementById('btn');
		btn.onclick = function () {
			var xhr = new XMLHttpRequest();
			xhr.open('get', 'http://localhost:3000/error');
			xhr.send();
			xhr.onload = function (){
				console.log(xhr.responseText);
				if (xhr.status == 400) { // xhr.status 获取http状态码
					alert('请求出错')
				}}
			xhr.onerror = function () { // 当网络中断时会触发onerrr事件
				alert('网络中断, 无法发送Ajax请求')
			}}
// app.js文件
app.get('/error', (req, res) => {
	// console.log(abc); 出现了服务器端500错误 声明了不存在的变量
	res.status(400).send('not ok');
});

7.低版本 IE浏览器的缓存问题

  • 在低版本的 IE浏览器中,Ajax 请求有严重的 缓存问题,即在 请求地址不发生变化 的情况下,只有第一次请求会真正发送到服务器端,后续的请求都会从浏览器的缓存中获取结果。即使服务器端的数据更新了,客户端依然拿到的是缓存中的旧数据
  • 解决方案:在请求地址的后面加请求参数,保证每一次请求地址不相同
  • xhr.open('get', 'http://www.example.com?t=' + Math.random());
// tml文件		btn.onclick = function () {
			var xhr = new XMLHttpRequest();
			xhr.open('get', 'http://localhost:3000/cache?t=' + Math.random());
			xhr.send();
			xhr.onreadystatechange = function (){
				if (xhr.readyState == 4 && xhr.status == 200) {
					alert(xhr.responseText);
				}}}
// app.js文件
app.get('/cache', (req, res) => {
	fs.readFile('./test.txt', (err, result) => {
		res.send(result);
	});
});

8.Ajax 封装

  • 问题:发送一次请求代码过多,冗余重复
  • 解决方案:将请求代码封装到函数中,发请求时调用函数
  • 请求参数要考虑的问题:请求参数位置的问题,请求参数格式的问题
  • 请求参数格式的问题:在 ajax函数内部,根据请求方式的不同,将请求参数放置在不同位置
  1. get 放在请求地址的后面
  2. post 放在send()方法中
  • 请求参数格式的问题:
  • application/x-www-form-urlencoded:参数名称=参数值&参数名称=参数值
  • application/json(推荐):{name: '茶茶子', age: 21}
  • 对象数据类型 对 函数调用者更友好,函数内部 对象数据类型 转换为 字符串数据类型更方便
		function ajax (options) {    // options用于接收实参,替换Ajax请求参数
			var defaults = {         // 存储默认值
				type: 'get',
				url: '',
				data: {},
				header: {
					'Content-Type': 'application/x-www-form-urlencoded'
				},
				success: function () {},
				error: function () {}
			};
			Object.assign(defaults, options); // 使用options对象中的属性覆盖defaults属性
			var xhr = new XMLHttpRequest();   // 创建ajax对象		
			var params = '';                  // 拼接请求参数的变量
			for (var attr in defaults.data) { // 循环用户传递进来的对象格式参数
				params += attr + '=' + defaults.data[attr] + '&'; // 将参数转字符串格式
			}
			// 将参数最后面的&截取掉,截取结果重新赋值给params变量
			params = params.substr(0, params.length - 1);	
			if (defaults.type == 'get') {                         // 判断请求方式
				defaults.url = defaults.url + '?' + params;
			}
			xhr.open(defaults.type, defaults.url);                // 配置ajax对象
			if (defaults.type == 'post') {                        // 如果请求方式为post
				// 用户希望的向服务器端传递的请求参数的类型
				var contentType = defaults.header['Content-Type']
				xhr.setRequestHeader('Content-Type', contentType); // 设置请求参数格式的类型
				// 如果类型为json
				if (contentType == 'application/json') { // 判断用户希望的请求参数格式的类型
				xhr.send(JSON.stringify(defaults.data))// 向服务器传递json数据格式的参数
				}else {
					xhr.send(params); // 向服务器端传递普通类型的请求参数
				}
			}else {
				// 发送请求
				xhr.send();
			}
			// 监听xhr对象下面的onload事件,当xhr对象接收完响应数据后触发
			xhr.onload = function () {
				// xhr.getResponseHeader():获取响应头中的数据
				var contentType = xhr.getResponseHeader('Content-Type');
				var responseText = xhr.responseText; // 服务器端返回的数据
				// 如果响应类型中包含applicaition/json
				if (contentType.includes('application/json')) {
					// 将json字符串转换为json对象
					responseText = JSON.parse(responseText)
				}
				// 当http状态码等于200的时候
				if (xhr.status == 200) {   // 请求成功 调用处理成功情况的函数
					defaults.success(responseText, xhr); 
				}else {                    // 请求失败 调用处理失败情况的函数
					defaults.error(responseText, xhr);
				}}}
		ajax({
			type: 'post',
			url: 'http://localhost:3000/responseData',
			success: function (data) {
				console.log('这里是success函数');
				console.log(data)
			}})

二.客户端模板引擎

  • 模板引擎:可以将 数据 和 HTML 拼接起来
  • 使用步骤:
  1. 下载 art-template 模板引擎库文件并在 html页面中引入,这指的是客户端模板引擎
  2. 准备 art-template模板,告诉模板引擎,数据 和 html字符串要如何拼接
  3. 告诉模板引擎 将哪个模板和哪个数据进行拼接
  4. 将拼接好的 html字符串添加到页面
  • 以前都是在服务器端实现 用模板引擎将数据+html拼接,现在将这部分放到 客户端 实现
  • <script type="text/html":令 script模板里的 html标签 得以正常实现效果,即模板引擎应写在 script里
	<!-- 1. 将模板引擎的库文件引入到当前页面 -->
	<script src="/js/template-web.js"></script>
</head>
<body>
	<div id="container"></div>
	<!-- 2.准备art-template模板 -->
	<script type="text/html" id="tpl">
		<h1>{{username}} {{age}}</h1>
	</script>
	<script type="text/javascript">
		// 3.告诉模板引擎将那个数据和哪个模板进行拼接 	// 1) 模板id 2)数据
		var html = template('tpl', {username: '茶茶子', age:21 });
                // 把拼接好的html字符串 写入页面
		document.getElementById('container').innerHTML = html;
	</script>
</body>

1.验证邮箱地址唯一性

  • 无需关心服务器如何检测,后端人员会提供 接口文档,前端人员只要调用里面的 参数/地址即可
  • 邮箱地址正则表达式:/^[A-Za-z\d]+([-_.][A-Za-z\d]+)*@([A-Za-z\d]+[-.])+[A-Za-z\d]{2,4}$/
  1. 获取文本框,添加离开焦点事件
  2. 失去焦点时,检测用户输入的邮箱地址是否符合规则
  3. 如果不符合规则,阻止程序向下执行并给出提示信息
  4. 向服务器端发送请求,检测邮箱地址是否被别人注册
  5. 根据服务器端返回值决定客户端显示何种提示信息
    	<script src="/js/ajax.js"></script> // 引入 ajax函数向服务器发送请求
	<script>
		var emailInp = document.getElementById('email');   // 输入框
		var info = document.getElementById('info');        // 提示信息
		emailInp.onblur = function () { // 当文本框失去焦点以后
			var email = this.value; // 获取用户输入的邮箱地址
			// 验证邮箱地址的正则表达式
			var reg = /^[A-Za-z\d]+([-_.][A-Za-z\d]+)*@([A-Za-z\d]+[-.])+[A-Za-z\d]{2,4}$/;
			if (!reg.test(email)) { // 如果用户输入的邮箱地址不符合规则
				
				info.innerHTML = '请输入符合规则的邮箱地址'; // 给出用户提示
				info.className = 'bg-danger'; // 给提示信息添加样式
				return; 	// 阻止程序向下执行 就是给服务器传递信息 判断邮箱是否被注册过
			}
			ajax({ // 向服务器端发送请求
				type: 'get',
				url: 'http://localhost:3000/verifyEmailAdress',
				data: {
					email: email // 第一个email是服务器规定,第二个是前面自定义
				},
				success: function (result) {
					console.log(result); // 验证成功在控制台打印服务器返回的信息
					info.innerHTML = result.message;
					info.className = 'bg-success';
				},
				error: function (result) {
					console.log(result)
					info.innerHTML = result.message;
					info.className = 'bg-danger';
				}});}
	</script>

2.搜索框内容自动提示

  1. 获取搜索框,添加用户输入事件,onInput()
  2. 获取用户输入的关键字key
  3. 向服务器端发送请求,携带关键字作为请求参数
  4. 将响应数据显示在搜索框底部
  • 为了防止重复发送无意义请求,给 ajax()添加定时器
	<script src="/js/ajax.js"></script>    // 引入ajax函数,向服务器发送请求
	<script src="/js/template-web.js"></script>    // 引入客户端模板引擎
	<script type="text/html" id="tpl">    // 引入客户端模板引擎,指定拼接模板
		{{each result}} // 遍历服务器返回的result,将result里的 值$value添加到里面
			<li class="list-group-item">{{$value}}</li>
		{{/each}}
	</script>
	<script>
		var searchInp = document.getElementById('search'); // 获取搜索框
		var listBox = document.getElementById('list-box'); // 获取关联文字列表
		var timer = null; // 存储定时器的变量,防止输入一个字母就向服务器提交一次请求
		
		searchInp.oninput = function () { // 当用户在文本框中输入的时候触发
			clearTimeout(timer); // 清除上一次开启的定时器
			var key = this.value; // 获取用户输入的内容
			if (key.trim().length == 0) { // 清空输入内容两边的空格,确保用户未输入内容
				listBox.style.display = 'none'; // 将提示下拉框隐藏掉	
				return; // 阻止程序向下执行 不像服务器发送请求
			}

			timer = setTimeout(function () { // 开启定时器 让请求延迟发送
				ajax({ // 向服务器端发送请求 索取和用户输入关键字相关的内容
					type: 'get',
					url: 'http://localhost:3000/searchAutoPrompt',
					data: {
						key: key // 服务器规定参数:获取的用户输入参数
					},
					success: function (result) {
						var html = template('tpl', {result: result});
						listBox.innerHTML = html; // 将拼接好的字符串显示在页面中
						listBox.style.display = 'block'; // 显示ul容器
					}})}, 800)}
	</script>

3.省市区三级联动​​​​​​​

  1. 获取省份信息,显示在下拉框中
  2. 为下拉框元素添加表单值改变事件(onchange)
  3. 当用户选择省份时,根据省份id 获取城市信息
  4. 当用户选择城市时,根据城市id 获取县城信息
<script src="/js/ajax.js"></script>
<script src="/js/template-web.js"></script>
	<!-- 省份模板 -->
	<script type="text/html" id="provinceTpl">
		<option>请选择省份</option>
		{{each province}}
			<option value="{{$value.id}}">{{$value.name}}</option>
		{{/each}}
	</script>
	<script type="text/html" id="cityTpl">
		<option>请选择城市</option>
        // ...同上
	<script type="text/html" id="areaTpl">
		<option>请选择县城</option>
        // ...同上
	<script>
		var province = document.getElementById('province');
		var city = document.getElementById('city');
		var area = document.getElementById('area');
		
		ajax({ // 向服务器发送请求 获取省份信息
			type: 'get',
			url: 'http://localhost:3000/province',
			success: function (data) {
				var html = template('provinceTpl', {province: data}); // 返回的是编号+名字
				province.innerHTML = html;
			}});
		province.onchange = function () { // 为省份的下拉框添加值改变事件
			var pid = this.value; // 获取省份id
			// 清空县城下拉框中的数据
			var html = template('areaTpl', {area: []});
			area.innerHTML = html;
			ajax({ // 根据省份id获取城市信息
				type: 'get',
				url: '/cities',
				data: {
					id: pid // 要传给服务器的数据
				},
				success: function (data) {
					var html = template('cityTpl', {city: data});
					city.innerHTML = html;
				}})};
		city.onchange = function () { // 为城市的下拉框添加值改变事件
			var cid = this.value; // 获取城市id
			ajax({ // 根据城市id获取县城信息
				type: 'get',
				url: 'http://localhost:3000/areas',
				data: {
					id: cid
				},
				success: function(data) {
					var html = template('areaTpl', {area: data});
					area.innerHTML = html;
				}})}
	</script>

三.FormData

  • FormData 对象作用:
  1. 将 HTML表单映射成表单对象,自动将表单对象中的数据,拼接成请求参数的格式
  2. 异步上传二进制文件(视频、图片)

1.模拟 HTML表单

  • FormData 对象使用:
  1. 准备 HTML 表单:不需要method、action属性,交给下面的 ajax进行判断
  2. 将 HTML表单 转化为 FormData对象
  3. 提交表单对象
  • FormData 对象注意:
  1. 不能用于 get 请求,因为对象被传递到 send()方法中,而 get 请求参数在请求地址后面
  2. 服务器端 bodyParser模块 不能解析 formData对象表单数据,需要使用 formidable模块 进行解析
  • FormData 对象实例方法:
  1. 获取表单对象中属性的值:formData.get('key');
  2. 设置表单对象中属性的值:formData.set('key', 'value');:比如用户没写年龄,客户端自动帮用户补充交给服务器端
  3. 删除表单对象中属性的值:formData.delete('key');:比如确认密码两遍,只会提交一次给客户端,需要删除一遍
  4. 追加表单对象中属性的值:formData.append('key', 'value');:和set功能类似
  • set() 与 append()区别:属性名已存在的情况下,set()覆盖已有键名的值,append()会保留两个值
  • 关于append(),服务器最终会接受 同一键名的两个值,但是只显示最后一个值
	<!-- 创建普通的html表单 -->
	<form id="form">
		<input type="text" name="username">
		<input type="password" name="password">
		<input type="button" id="btn" value="提交">
	</form>
	<script type="text/javascript">
		var btn = document.getElementById('btn');       // 获取提交按钮
		var form = document.getElementById('form');     // 获取表单对象
		btn.onclick = function () {
			// 将普通的html表单 转换为 表单对象
			var formData = new FormData(form);
			var xhr = new XMLHttpRequest(); // 创建ajax对象
            formData.set('age', 21); // set:覆盖原来的值/添加表单原来没有的属性
			formData.append('username', '茶茶子'); // append:保留两个值
            formData.delete('password');
			xhr.open('post', 'http://localhost:3000/formData'); // 对ajax对象进行配置
			xhr.send(formData);                                 // 提交表单对象
			xhr.onload = function () {                          // 监听xhr对象的onload事件
				if (xhr.status == 200) {                    // 对象http状态码进行判断
					console.log(xhr.responseText);
				}}}
            // 创建空的表单对象
	        var f = new FormData();
			        f.append('sex', '男');
			        console.log(f.get('sex'));
		            }
	</script>

// app.js 服务器端代码
const formidable = require('formidable');
app.post('/formData', (req, res) => {
	const form = new formidable.IncomingForm(); // 创建formidable表单解析对象
	// 解析客户端传递过来的 FormData对象
	form.parse(req, (err, fields, files) => {
		res.send(fields);
	});});

2.异步上传二进制文件

  • FormData 二进制文件上传:
  • 当用户选择文件时触发:file.onchange()
  • FormData 文件上传进度条展示:
  • 文件上传过程中持续触发 onprogress事件:xhr.uplode.onprogress = function(ev)
  • FormData 文件上传图片即时预览:
  • 将图片上传到服务器端后,服务器端通常将 图片地址 做为响应数据传递到客户端
  • 客户端可以从 响应数据中 获取图片地址,然后显示图片
<div class="container">
		<div class="form-group">
			<input type="file" id="file">   // 文件选择区
			<div class="padding" id="box">  // 图片预览区
				<!--<img src="" class="img-rounded img-responsive">--></div>
			<div class="progress">          // 进度条
				<div class="progress-bar" style="width: 0%;" id="bar">0%</div></div>
		</div>
	</div>
	<script type="text/javascript">
		var file = document.getElementById('file'); // 获取文件选择控件
		var bar = document.getElementById('bar');   // 获取进度条元素
		var box = document.getElementById('box');   // 获取图片容器
		// 为文件选择控件添加onchanges事件 在用户选择文件时触发
		file.onchange = function () { 
			var formData = new FormData();              // 创建 空的formData表单对象
			// 将用户选择的文件追加到formData表单对象中,attrName自己取的名
			formData.append('attrName', this.files[0]); // this.files[0]第一个文件
			var xhr = new XMLHttpRequest();             // 创建ajax对象
			xhr.open('post', 'http://localhost:3000/upload'); // 对ajax对象进行配置	
			xhr.upload.onprogress = function (ev) {     // 在文件上传的过程中持续触发
				// ev.loaded 文件已经上传了多少
				// ev.total  上传文件的总大小
				var result = (ev.loaded / ev.total) * 100 + '%';
				bar.style.width = result; // 设置进度条的宽度
				bar.innerHTML = result;   // 将百分比显示在进度条中 
			}
			xhr.send(formData);         // 发送ajax请求
			xhr.onload = function () {  // 监听服务器端响应给客户端的数据
				// 如果服务器端返回的http状态码为200 说明请求是成功的
				if (xhr.status == 200) {
					// 将服务器端返回的数据显示在控制台中
					var result = JSON.parse(xhr.responseText);
					var img = document.createElement('img'); // 动态创建img标签
					img.src = result.path;     // 给图片标签设置src属性
					img.onload = function () { // 当图片加载完成以后
					    box.appendChild(img);      // 将图片显示在页面中
					}}}}
	</script>

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Lyrelion

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值