1、Ajax的运行原理以及实现
1.1 Ajax的运行环境
使用node开启服务器,代码写在html中,再放进静态资源文件夹中,就可以使用域名访问了
1.2 Ajax的运行原理
实现无刷新更新数据,边浏览边请求响应。并且ajax请求和响应是可控的,并且可以反馈给用户。
1.3 Ajax的实现步骤
首先开启服务器 nodemon app.js
<script type="text/javascript"> //客户端
// 1.创建ajax对象
var xhr = new XMLHttpRequest();
// 2.告诉Ajax对象要向哪发送请求,以什么方式发送请求
// 1)请求方式 2)请求地址
xhr.open("get", "http://localhost:3000/first");
// 3.发送请求
xhr.send();
// 4.获取服务器端响应到客户端的数据
xhr.onload = function () {
console.log(xhr.responseText);
};
</script>
// 对应01html文件 服务器段
app.get('/first', (req, res) => {
res.send('Hello, Ajax'); //为客户端响应文字
});
因为send(0 方法后,接受会受网络的影响,所以写一个onload等待他的响应
监听xhr对象的onload事件,完成之后获取响应数据console.log(xhr.responseText);这里面就是res.send(“ Hello,Ajax”) 但是知识字符串格式。
JSON.parse()方法,它是Windows下面的方法
xhr.onload = function (){
// console.log(typeof xhr.responseText)
// 将JSON字符串转换为JSON对象
var responseText = JSON.parse(xhr.responseText);
// 测试:在控制台输出处理结果
console.log(responseText)
// 将数据和html字符串进行拼接
var str = '<h2>'+ responseText.name +'</h2>';
// 将拼接的结果追加到页面中
document.body.innerHTML = str;
}
需要把json字符串转换为json对象,此时上面的responseText就是一个对象了。接受的json和html拼接,然后添加DOM到html中,
1.4 请求参数的传递
传统网站
1.4.1 GET的提交
其实就是open()里面的参数写法改变了
<script type="text/javascript">
// 获取按钮元素
var btn = document.getElementById('btn');
// 获取姓名文本框
var username = document.getElementById('username');
// 获取年龄文本框
var age = document.getElementById('age');
// 为按钮添加点击事件
btn.onclick = function () {
// 创建ajax对象
var xhr = new XMLHttpRequest();
// 获取用户在文本框中输入的值
var nameValue = username.value;
var ageValue = age.value;
// 拼接请求参数
var params = 'username='+ nameValue +'&age=' + ageValue;
// 配置ajax对象
xhr.open('get', 'http://localhost:3000/get?'+params);
// 发送请求
xhr.send();
// 获取服务器端响应的数据
xhr.onload = function () {
console.log(xhr.responseText)
}
}
</script>
app.get('/get', (req, res) => {
res.send(req.query);
});
req.query对象就是服务器端接受客户端传过来的GET请求参数,res.send(req.query);再把它响应到客户端。
1.4.1 POST的提交
post是放在send()中的
btn.onclick = function () {
// 创建ajax对象
var xhr = new XMLHttpRequest();
// 获取用户在文本框中输入的值
var nameValue = username.value;
var ageValue = age.value;
// 拼接请求参数
var params = 'username='+ nameValue +'&age=' + ageValue;
// 配置ajax对象
xhr.open('post', 'http://localhost:3000/post');
// 设置请求参数格式的类型(post请求必须要设置)
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
// 发送请求
xhr.send(params);
// 获取服务器端响应的数据
xhr.onload = function () {
console.log(xhr.responseText)
}
// 服务器端对于post的请求参数要用const bodyParser = require('body-parser');
app.post('/post', (req, res) => {
res.send(req.body); //相应回客户端
});
var params = 'username='+ nameValue +'&age=' + ageValue;
如果请求参数是params中的,那么下面就是固定写法
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
1.5 请求参数的格式
请求方式必须是post,get请求不能提交json对象数据格式
请求头必须是 "application/json"
必须转换成字符串类型
<script type="text/javascript">
// 1.创建ajax对象
var xhr = new XMLHttpRequest();
// 2.告诉Ajax对象要向哪发送请求,以什么方式发送请求
// 1)请求方式 2)请求地址
xhr.open("post", "http://localhost:3000/json");
// 通过请求头告诉服务器端 客户端向服务器端传递的请求参数的格式是什么
xhr.setRequestHeader("Content-Type", "application/json");
// JSON.stringify() 将json对象转换为json字符串
// 3.发送请求
xhr.send(JSON.stringify({ name: "lisi", age: 50 }));
// 4.获取服务器端响应到客户端的数据
xhr.onload = function () {
console.log(xhr.responseText);
};
</script>
获得服务器端的响应(Ajax状态码)
获取Ajax状态码,xhr.readyState //获取Ajax状态码
<script type="text/javascript">
var xhr = new XMLHttpRequest();
// 0 已经创建了ajax对象 但是还没有对ajax对象进行配置
console.log(xhr.readyState);
xhr.open("get", "http://localhost:3000/readystate");
// 1 已经对ajax对象进行配置 但是还没有发送请求
console.log(xhr.readyState);
// 当ajax状态码发生变化的时候出发
xhr.onreadystatechange = function () {
// 2 请求已经发送了
// 3 已经接收到服务器端的部分数据了
// 4 服务器端的响应数据已经接收完成
console.log(xhr.readyState);
// 对ajax状态码进行判断 如果状态码的值为4就代表数据已经接收完成了
if (xhr.readyState == 4) {
console.log(xhr.responseText);
}
};
xhr.send();
</script>
app.get('/readystate', (req, res) => {
res.send('hello');
});
xhr.onreadystatechange = function () 状态码发生变化时候自动触发
res.send('hello'); 是发送给服务器的 console.log(xhr.responseText);是获取服务器的数据
1.6 Ajax错误处理
<script type="text/javascript">
var btn = document.getElementById('btn');
btn.onclick = function () {
// 1.创建ajax对象
var xhr = new XMLHttpRequest();
// 2.告诉Ajax对象要向哪发送请求,以什么方式发送请求
// 1)请求方式 2)请求地址
xhr.open('get', 'http://localhost:3000/error');
// 3.发送请求
xhr.send();
// 4.获取服务器端响应到客户端的数据
xhr.onload = function (){
// xhr.status 获取http状态码
console.log(xhr.responseText);
if (xhr.status == 400) {
alert('请求出错')
}
}
// 当网络中断时会触发onerrr事件
xhr.onerror = function () {
alert('网络中断, 无法发送Ajax请求')
}
}
</script>
// Ajax状态码: 表示Ajax请求的过程状态 ajax对象返回的
// Http状态码: 表示请求的处理结果 是服务器端返回的
低版本IE浏览器的缓存问题,浏览器会从缓存之中取上一次的服务器响应结果,而不是实时的响应
解决方案:xhr.open('get', 'http://localhost:3000/cache?t=' + Math.random()); 每次让请求地址不一样
2 Ajax异步编程
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
console.log("2");
console.log(xhr.responseText);
}
};
console.log("1");
输出顺序:1 2
2.1 Ajax封装
最后的data就是请求结果
function ajax(options){
var xhr = new XMLHttpRequest();
xhr.open(options.type,option.url)
xhr.send()
xhr.onload = function(){
options.success(xhr.responseText)
}
}
ajax({
type: "post",
// 请求地址
url: "http://localhost:3000/responseData",
success: function (data) {
console.log("这里是success函数");
console.log(data);
},
});
如果需要其他的参数传递进去function ajax,怎么办?
请求参数要考虑的问题:
1.请求参数位置的问题
将请求参数传递到ajax函数内部, 在函数内部根据请求方式的不同将请求参数放置在不同的位置 get 放在请求地址的后面、post 放在send方法中
2.请求参数格式的问题
application/x-www-form-urlencoded 参数名称=参数值&参数名称=参数值 name=zhangsan&age=20
application/json {name: 'zhangsan', age: 20}
下面这段代码必须读懂
function ajax(options) {
// 存储的是默认参数
var defaults = {
type: "get",
url: "",
data: {},
header: {
"Content-Type": "application/x-www-form-urlencoded",
},
success: function () {},
error: function () {},
};
// 使用options对象中的属性覆盖defaults对象中的属性
Object.assign(defaults, options);
// 创建ajax对象
var xhr = new XMLHttpRequest();
// 拼接请求参数的变量
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;
}
/*
{ name: 'zhangsan',
age: 20 }
name=zhangsan&age=20
*/
// 配置ajax对象
xhr.open(defaults.type, defaults.url);
// 如果请求方式为post
if (defaults.type == "post") {
// 用户希望的向服务器端传递的请求参数的类型
var contentType = defaults.header["Content-Type"];
// 设置请求参数格式的类型
xhr.setRequestHeader("Content-Type", contentType);
// 判断用户希望的请求参数格式的类型
// 如果类型为json
if (contentType == "application/json") {
// 向服务器端传递json数据格式的参数 JSON转换成json字符串
xhr.send(JSON.stringify(defaults.data));
} else {
// 向服务器端传递普通类型的请求参数
xhr.send(params);
}
} else {
// 发送请求
xhr.send();
}
// 监听xhr对象下面的onload事件
// 当xhr对象接收完响应数据后触发
xhr.onload = function () {
// xhr.getResponseHeader()
// 获取响应头中的数据 就是application/json还是text/html
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);
},
});
3 客户端模板引擎
原本是服务器给你拼好传递给你,现在你客户端自己拼接数据和html
1 使用步骤
注意:客户端的JavaScript不具备读取文件的能力,所以在客户端模板不是单独的文件,而是html文件中的代码片段,并且用script包裹。通过id=“tp1”区分模板。
但是<script>内部的编辑器默认将其作为js语法解析,可以在<script>添加属性,这样就可以将它作为html代码执行。
其实就是写一个模板 <script type="text/html" id="tpl"> </script>
然后把数据拼接模板template()
然后返回拼接好的返回到使用的地方
<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)数据 对象类型
// 方法的返回值就是拼接好的html字符串
var html = template("tpl", { username: "zhangsan", age: 30 });
// template返回<h1>zhangsan 30</h1>
document.getElementById("container").innerHTML = html;
</script>
</body>
2. 案例
思路逻辑4
4. FormData
4.1 FormData的作用
注意:FormData只适用于post方式而不是get,应为要放在send()中。
<script type="text/javascript">
// 获取按钮
var btn = document.getElementById('btn');
// 获取表单
var form = document.getElementById('form');
// 为按钮添加点击事件
btn.onclick = function () {
// 将普通的html表单转换为表单对象
var formData = new FormData(form);
// 创建ajax对象
var xhr = new XMLHttpRequest();
// 对ajax对象进行配置
xhr.open('post', 'http://localhost:3000/formData');
// 发送ajax请求
xhr.send(formData);
// 监听xhr对象下面的onload事件
xhr.onload = function () {
// 对象http状态码进行判断
if (xhr.status == 200) {
console.log(xhr.responseText);
}
}
}
</script>
app.post('/formData', (req, res) => {
// 创建formidable表单解析对象
const form = new formidable.IncomingForm();
// 解析客户端传递过来的FormData对象
form.parse(req, (err, fields, files) => {
res.send(fields);
});
});
4.2 FormData对象的实例方法
get('key') 获取表单对象属性的值
set('key', 'value') 设置表单对象属性的值
delete('key') 删除表单对象属性中的值
append('key', 'value')追加属性以及值
注意:append和set都会追加值,因为set没有,设置后会追加,两个不同的区别就是在属性名已存在的前提下,set会覆盖原来的value,append会保留两个值,但是服务器端默认会接受最后一个value,如果是先set然后append,那么接受的就是append的value
formData.set("username", "itcast");
formData.append("username", "itheima");
// 如果设置的表单属性不存在 将会创建这个表单属性
formData.set("age", 100);
// 删除用户输入的密码
formData.delete("password");
4.3 FormData 二进制文件上传 同时实现文件上传图片即时预览
get不能用于文件上传!!!!!!!!
这个案例要好好看看
上传文件中使用事件对象 xhr.upload.onprogress = function (ev)可以记录进度条
<div class="progress">
//进度条
<div class="progress-bar" style="width: 0%" id="bar">0%</div>
</div>
// 获取文件选择控件
var file = document.getElementById("file");
// 获取进度条元素
var bar = document.getElementById("bar");
// 获取图片容器
var box = document.getElementById("box");
// 为文件选择控件添加onchanges事件
// 在用户选择文件时触发
file.onchange = function () {
// 创建空的formData表单对象
var formData = new FormData();
// 将用户选择的文件追加到formData表单对象中
formData.append("attrName", this.files[0]);
// 创建ajax对象
var xhr = new XMLHttpRequest();
// 对ajax对象进行配置
xhr.open("post", "http://localhost:3000/upload");
// 在文件上传的过程中持续触发
xhr.upload.onprogress = function (ev) {
// ev.loaded 文件已经上传了多少
// ev.total 上传文件的总大小
var result = (ev.loaded / ev.total) * 100 + "%";
// 设置进度条的宽度
bar.style.width = result;
// 将百分比显示在进度条中
bar.innerHTML = result;
}};
app.post('/upload', (req, res) => {
// 创建formidable表单解析对象
const form = new formidable.IncomingForm();
// 设置客户端上传文件的存储路径
form.uploadDir = path.join(__dirname, 'public', 'uploads');
// 保留上传文件的后缀名字
form.keepExtensions = true;
// 解析客户端传递过来的FormData对象
form.parse(req, (err, fields, files) => {
// 将客户端传递过来的文件地址响应到客户端
res.send({
path: files.attrName.path.split('public')[1]
});
});
});
app.post('/upload', (req, res) => {
// 创建formidable表单解析对象
const form = new formidable.IncomingForm();
// 设置客户端上传文件的存储路径
form.uploadDir = path.join(__dirname, 'public', 'uploads');
// 保留上传文件的后缀名字
form.keepExtensions = true;
// 解析客户端传递过来的FormData对象
form.parse(req, (err, fields, files) => {
// 将客户端传递过来的文件地址响应到客户端
res.send({
path: files.attrName.path.split('public')[1] //返回服务器端电脑的硬盘地址 切割并且拿出来图片});})});
注意这个files.attrName.path.split('public')[1]。file是send最后一个参数,attrName是上传时候设置的名字,下面有一个path属性
split切割后,
5、同源政策
5.1 什么是同源
如果两个页面拥有相同的协议、域名和端口,那么这两个页面就属于一个源,其中一个不一样就是不同源。
5.2 同源政策的目的
5.3 使用JSONP解决同源限制的问题
利用script代码可以向非同源服务器发送请求的特性, 加载完之后,就可以在客户端被调用,此时客户端要提前写好这个函数,而且是写在script前面。
jsonp全名就是在服务器端把json数据作为参数 返回给客户端定义的函数
比如下面的是Jquery的js文件的不同源服务器访问,script标签的src属性不受同源政策的影响
<body>
<script>
function fn (data) {
console.log('客户端的fn函数被调用了')
console.log(data);
}
</script>
<!-- 1.将非同源服务器端的请求地址写在script标签的src属性中 -->
<script src="http://localhost:3001/test"></script>
</body>
app.get('/test', (req, res) => {
const result = 'fn({name: "张三"})';
res.send(result);
});
<script src="http://localhost:3001/test"></script> 结束后,会调用一个函数,就是上面的,这个函数的调用是服务器端发起的
5.4 JSONP代码优化
5.4.1 动态创建
之前:请求在访问html页面时候发文
现在:设置成点击按钮再发送请求之类的(其实就是动态创建script标签)创建就会发送,发送请求后再把这个script标签删除。
5.4.2 函数名字优化
5.4.3 jsonp封装
把函数放进success,然后再定义为全局变函数。
注意:服务器端的res.jsonp方法,就是上面注释掉的
<body>
<button id="btn1">点我发送请求</button>
<button id="btn2">点我发送请求</button>
<script type="text/javascript">
// 获取按钮
var btn1 = document.getElementById("btn1");
var btn2 = document.getElementById("btn2");
// 为按钮添加点击事件
btn1.onclick = function () {
jsonp({
// 请求地址
url: "http://localhost:3001/better",
data: {
name: "lisi",
age: 30,
},
success: function (data) {
//匿名函数!!!!没有名字
console.log(123);
console.log(data);
},
});
};
btn2.onclick = function () {
jsonp({
// 请求地址
url: "http://localhost:3001/better",
success: function (data) {
console.log(456789);
console.log(data);
},
});
};
function jsonp(options) {
// 动态创建script标签
var script = document.createElement("script");
// 拼接字符串的变量
var params = "";
for (var attr in options.data) {
params += "&" + attr + "=" + options.data[attr];
}
// myJsonp0124741 因为后面的会覆盖前面的函数名 所以要随机
// 生成随机数.转换字符串.把“.”转换为空
var fnName = "myJsonp" + Math.random().toString().replace(".", "");
// 它已经不是一个全局函数了(因为写在了success中)
// 我们要想办法将它变成全局函数,挂在Windows下
window[fnName] = options.success;
// 为script标签添加src属性
script.src = options.url + "?callback=" + fnName + params;
// 将script标签追加到页面中
document.body.appendChild(script);
// 为script标签添加onload事件
script.onload = function () {
document.body.removeChild(script);
};
}
</script>
</body>
app.get('/better', (req, res) => {
// 接收客户端传递过来的函数的名称
//const fnName = req.query.callback;
// 将函数名称对应的函数调用代码返回给客户端
//const data = JSON.stringify({name: "张三"});
//const result = fnName + '('+ data +')';
// setTimeout(() => {
// res.send(result);
// }, 1000)
res.jsonp({name: 'lisi', age: 20});
});
5.4.4 jsonp获取腾讯天气的信息
使用了客户端的模板引擎 box.innerHTML = html; //模板的拼接结果
注意定义了处理日期的方法把2010091010改编成年月日的形式:
做法:定义处理日期的方法,方法在模板被调用。只需要在模板中暴露外部变量,这个变量可以是一个函数。 template.defaults.imports.dateFormat = dateFormat;
最右边的dateFormat是一个函数
<body>
<div class="container">
<table
class="table table-striped table-hover"
align="center"
id="box"
></table>
</div>
<script src="/js/jsonp.js"></script>
<script src="/js/template-web.js"></script>
<script type="text/html" id="tpl">
<tr>
<th>时间</th>
<th>温度</th>
<th>天气</th>
<th>风向</th>
<th>风力</th>
</tr>
{{each info}}
<tr>
<td>{{dateFormat($value.update_time)}}</td>
<td>{{$value.degree}}</td>
<td>{{$value.weather}}</td>
<td>{{$value.wind_direction}}</td>
<td>{{$value.wind_power}}</td>
</tr>
{{/each}}
</script>
<script>
// 获取table标签
var box = document.getElementById("box");
function dateFormat(date) {
var year = date.substr(0, 4);
var month = date.substr(4, 2);
var day = date.substr(6, 2);
var hour = date.substr(8, 2);
var minute = date.substr(10, 2);
var seconds = date.substr(12, 2);
return (
year +
"年" +
month +
"月" +
day +
"日" +
hour +
"时" +
minute +
"分" +
seconds +
"秒"
);
}
// 向模板中开放外部变量
template.defaults.imports.dateFormat = dateFormat;
// 向服务器端获取天气信息
jsonp({
url: "https://wis.qq.com/weather/common",
data: {
source: "pc",
weather_type: "forecast_1h",
// weather_type: 'forecast_1h|forecast_24h',
province: "黑龙江省",
city: "哈尔滨市",
},
success: function (data) {
var html = template("tpl", { info: data.data.forecast_1h });
box.innerHTML = html; //模板的拼接结果
},
});
</script>
</body>
5.5 CORS 跨域资源共享
就是它允许浏览器向跨域服务器发Ajax请求,在服务器端配置。
同意请求后,响应头会加进去点东西,就是一个白名单
// 拦截所有请求
app.use((req, res, next) => {
// 1.允许哪些客户端访问我
// * 代表允许所有的客户端访问我
// 注意:如果跨域请求中涉及到cookie信息传递,值不可以为*号 比如是具体的域名信息
res.header('Access-Control-Allow-Origin', 'http://localhost:3000')
// 2.允许客户端使用哪些请求方法访问我
res.header('Access-Control-Allow-Methods', 'get,post')
// 允许客户端发送跨域请求时携带cookie信息
res.header('Access-Control-Allow-Credentials', true);
next();
});
因为不可能对所有的路由加进去res.header()这个方法,所以用express中间件先行拦截所有的请求。app.use()
5.6 访问非同源数据 服务器端解决方案
A浏览器可以访问A 但是不能访问B服务器因为不同源,但是A服务器端可以访问B服务器端,所以让A服务器端当工具人。
使用request模块让服务器端来相互访问数据
const request = require('request');
app.get('/server', (req, res) => {
request('http://localhost:3001/cross', (err, response, body) => {
res.send(body);
})
});
request()中的body就是B给A的响应,A再res.send(body)发给A浏览器端
5.7 cookie复习
相当于这个响应cooki就是服务器端发送给客户端的身份证,下次客户端发送请求会自动加上这个身份证,但是使用Ajax跨域时候,就不会自动加上这个身份证
withCredentials属性
按理来说,登录成功后,点击检测用户登录状态 显示“处于未登录状态”因为
必须同时设置
res.header('Access-Control-Allow-Credentials', true); 服务器端的设置
xhr.withCredentials = true; 客户端的设置
6、$Ajax()
$("#btn").on("click", function () {
$.ajax({
// 请求方式
type: "post",
// 请求地址
url: "/base",
// 请求成功以后函数被调用
success: function (response) {
// response为服务器端返回的数据
// 方法内部会自动将json字符串转换为json对象
console.log(response);
},
// 请求失败以后函数被调用
error: function (xhr) {
console.log(xhr);
},
});
});
如果文件地址和请求地址,域名协议端口相同,只用写一个/base就行
beforeSend() 方法,在发送之前做一点事情,再觉得是否发送请求。
$("#btn").on("click", function () {
$.ajax({
// 请求方式
type: "post",
// 请求地址
url: "/user",
// 在请求发送之前调用 请求发送之前做一点事情
beforeSend: function () {
alert("请求不会被发送");
// 请求不会被发送
return false;
},
// 请求成功以后函数被调用
success: function (response) {
// response为服务器端返回的数据
// 方法内部会自动将json字符串转换为json对象
console.log(response);
},
});
});
serialize()方法表单内容拼接成字符串类型的参数
$("#form").on("submit", function () {
// 将表单内容拼接成字符串类型的参数
// var params = $('#form').serialize();
// console.log(params)
serializeObject($(this));
return false; });最后的 return false;是为了防止表单自动提交
<script type="text/javascript">
$("#form").on("submit", function () {
// 将表单内容拼接成字符串类型的参数
// var params = $('#form').serialize();
// console.log(params)
serializeObject($(this));
return false;
});
// 将表单中用户输入的内容转换为对象类型
function serializeObject(obj) {
// 处理结果对象
var result = {};
// [{name: 'username', value: '用户输入的内容'},
// {name: 'password', value: '123456'}]
var params = obj.serializeArray();
// 循环数组 将数组转换为对象类型
$.each(params, function (index, value) {
result[value.name] = value.value;
});
// 将处理的结果返回到函数外部
return result;
}
</script>
$.each(params, function (index, value) {
result[value.name] = value.value; });params是循环的参数,后面是回调函数。循环几次执行几次
index是索引,index0对应 {name: 'username', value: '用户输入的内容'},
index2对应 {name: 'password', value: '123456'}
6.1 $Ajax发送jsonp请求
<script>
function fn(response) {
console.log(response);
}
$("#btn").on("click", function () {
$.ajax({
url: "/jsonp",
// 向服务器端传递函数名字的参数名称
jsonp: "cb",
jsonpCallback: "fn",
// 代表现在要发送的是jsonp请求
dataType: "jsonp" /*,
success: function (response) {
console.log(response)
}*/,
});
});
</script>
app.get('/jsonp', (req, res) => {
const cb = req.query.cb
const data = cb+"({name: 'zhaoliu'})"
res.send(data);
// res.jsonp({
// name: 'lisi',
// age:50
// })
});
6.2 $get() $post()
function(response)就相当于success函数,第二个参数可以不写。
6.3 jQuery中的Ajax全局事件
全局事件:只要有Ajax发送,对应的全局事件就会被触发
.........
6. XML基础
作用:传输和存储数据
app.get('/xml', (req, res) => {
res.header('content-type', 'text/xml'); //这是一定要写的
res.send('<message><title>消息标题</title><content>消息内容</content></message>')
});
<script type="text/javascript">
var btn = document.getElementById("btn");
var container = document.getElementById("container");
btn.onclick = function () {
var xhr = new XMLHttpRequest();
xhr.open("get", "/xml");
xhr.send();
xhr.onload = function () {
// xhr.responseXML 获取服务器端返回的xml数据
var xmlDocument = xhr.responseXML;
var title = xmlDocument.getElementsByTagName("title")[0].innerHTML;
container.innerHTML = title;
};
};
</script>
7、GIt管理工具
只存储被修改的文件在 暂存区 然后提交到仓库
查看分支
jinbo@harderfucker MINGW64 /d/software Vscode/学习代码/Node.js/15-16阿里百秀/day01/code/git-demo (master)
$ git branch
* master
jinbo@harderfucker MINGW64 /d/software Vscode/学习代码/Node.js/15-16阿里百秀/day01/code/git-demo (master)
$ git branch develop
jinbo@harderfucker MINGW64 /d/software Vscode/学习代码/Node.js/15-16阿里百秀/day01/code/git-demo (master)
$ git branch
develop
* master
jinbo@harderfucker MINGW64 /d/software Vscode/学习代码/Node.js/15-16阿里百秀/day01/code/git-demo (master)
$ git checkout develop
Switched to branch 'develop'
jinbo@harderfucker MINGW64 /d/software Vscode/学习代码/Node.js/15-16阿里百秀/day01/code/git-demo (develop)
$ git branch
* develop
master
jinbo@harderfucker MINGW64 /d/software Vscode/学习代码/Node.js/15-16阿里百秀/day01/code/git-demo (develop)
$ git add develop.html
jinbo@harderfucker MINGW64 /d/software Vscode/学习代码/Node.js/15-16阿里百秀/day01/code/git-demo (develop)
$ git status
On branch develop
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: develop.html
jinbo@harderfucker MINGW64 /d/software Vscode/学习代码/Node.js/15-16阿里百秀/day01/code/git-demo (develop)
$ git checkout master
Switched to branch 'master'
A develop.html
jinbo@harderfucker MINGW64 /d/software Vscode/学习代码/Node.js/15-16阿里百秀/day01/code/git-demo (master)
$ git checkout develop
Switched to branch 'develop'
A develop.html
jinbo@harderfucker MINGW64 /d/software Vscode/学习代码/Node.js/15-16阿里百秀/day01/code/git-demo (develop)
$ git commit -m 开发分支的第一次提交
[develop 75fd288] 开发分支的第一次提交
1 file changed, 1 insertion(+)
create mode 100644 develop.html
jinbo@harderfucker MINGW64 /d/software Vscode/学习代码/Node.js/15-16阿里百秀/day01/code/git-demo (develop)
$ git checkout master
Switched to branch 'master'
jinbo@harderfucker MINGW64 /d/software Vscode/学习代码/Node.js/15-16阿里百秀/day01/code/git-demo (master)
$ git checkout develop
Switched to branch 'develop'
jinbo@harderfucker MINGW64 /d/software Vscode/学习代码/Node.js/15-16阿里百秀/day01/code/git-demo (develop)
$
注意:
之前是必须提交,才能切换分支,现在是临时保存 git stash
也就是你git stash后,可以切换分支,去干别的活,等你切换回原来分支后,可以git stash pop
8 Ajax中的模板引擎
由于服务器端返回的都是数组或者json对象,前端不能直接显示数组或者对象,必须要拼接进去html标签中,再通过DOM方法设置进去页面
不用模板引擎的问题:1、代码轮换 2、逻辑复杂
8.1 模板引擎的作用
模板渲染, <script type="text/html" id="tpl"> type是text/html,这样的话就支持语法高亮
<script src="js/template-web.js"></script>
<script type="text/html" id="tpl">
<div>
<span>姓名:{{name}}</span>
<span>年龄:{{age}}</span>
</div>
</script>
// 这是告诉模板引擎将模板id为tpl的模板和data数据对象进行拼接
var html = template("tpl", data);
/* console.log(html);
<div>
<span>姓名:{{name}}</span>
<span>年龄:{{age}}</span>
</div> */
document.getElementById("container").innerHTML = html;
8.2 模板引擎的技巧
8.2.1 原文输出
在模板里面 @
<div>
<span>姓名:{{@ name}}</span>
<span>年龄:{{age}}</span>
</div>
var data = {
name: "<b>李四</b>",
age: 30,
};
8.2.2 条件判断
<script type="text/html" id="tpl">
<div>
<span>姓名:{{@ name}}</span>
<span>年龄:{{age}}</span>
</div>
{{if age > 18}}
<div>年龄大于18</div>
{{else}}
<div>年龄小于18</div>
{{/if}}
</script>
var data = {
name: '<b>李四</b>',
age: 25
}
8.2.3 循环
each data中的data是数组 value指的是 {name: "张三", age: 15, }, value.name就是张三,value.age就是15
<script type="text/html" id="tpl">
<ul>
{{each data}}
<li>
<span>姓名:{{$value.name}}</span>
<span>年龄:{{$value.age}}</span>
</li>
{{/each}}
</ul>
</script>
var html = template("tpl", {
data: [
{
name: "张三",
age: 15,
},
{
name: "李四",
age: 20,
},
{
name: "王五",
age: 10,
},
],
});
8.2.4 导入模板变量
<script type="text/html" id="tpl">
<div>当前时间是:{{$imports.dateFormat(date)}}</div>
</script>
<script>
// 这是告诉模板引擎将模板id为tpl的模板和data数据对象进行拼接
var html = template("tpl", { date: new Date(), });
document.getElementById("container").innerHTML = html;
function dateFormat(date) {
console.log(date); //Tue Nov 08 2022 16:39:08 GMT+0800 (中国标准时间)
return (
date.getFullYear() + "年" + (date.getMonth() + 1) +
"月" + date.getDate() + "日"
);
}
</script>
但是有的时候会这样写,在外面包裹一层 window.onload() 当页面加载完成后执行函数体内部的代码,此时function dateFormat(date)不是全局的函数了, 但是可以导入到模板中,成为模板函数。
但是 template.defaults.imports.dateFormat = dateFormat;要放在函数定义的前面
<script>
window.onload = function () {
// 将方法导入到模板中
template.defaults.imports.dateFormat = dateFormat;
// 这是告诉模板引擎将模板id为tpl的模板和data数据对象进行拼接
var html = template("tpl", {
date: new Date(),
});
document.getElementById("container").innerHTML = html;
function dateFormat(date) {
console.log(date); //Tue Nov 08 2022 16:39:08 GMT+0800 (中国标准时间)
return (
date.getFullYear() +
"年" + (date.getMonth() + 1) + "月" + date.getDate() + "日" );
}
};
</script>