Ajax
1. Ajax基础
1.1 传统网站中存在的问题
- 网速慢的情况下,页面加载时间长,用户只能等待
- 表单提交后,如果一项内容不合格,需要重新填写表单内容
- 页面跳转,重新加载页面,造成资源浪费,增加用户等待时间
1.2 Ajax概述
它是浏览器提供的一套方法,可以实现页面无刷新更新数据,提高用户浏览网站应用体验
1.3 Ajax的应用场景
- 页面加载更多数据
- 列表无刷新分页
- 表单项离开焦点数据验证
- 搜索框提示文字下拉列表
1.4 Ajax的运行环境
Ajax技术需要运行在网站环境中才能生效,
1.5 Ajax的实现步骤
- 创建Ajax对象
var xhr=new XMLHttpRequest()
- 告诉Ajax请求地址以及请求方式
- 第一个参数是请求方式,第二个参数是请求地址
xhr.open('get','http://www.')
- 发送请求
xhr.send()
- 获取服务器端给客户端响应数据
- xhr.responseText保存服务器端响应的数据
xhr.onload = function () {
console.log(xhr.responseText)
}
-
获取服务器端的响应第二种方法
Ajax状态码
在创建Ajax对象,配置Ajax对象发送请求,以及接收完服务器端响应的数据,这个过程中每一个步骤都会对应一个数值,这个数值就Ajax状态码
-
0:请求末初始化(还没有调用open()方法)
-
1:请求已经建立,但是还没有发送(还没调用send()方法)
-
2:代表已经发送
-
3:请求正在处理中,通常响应中已经有部分数据可以用了
-
4:响应已经完成,可以获取并使用服务器的响应了
xhr.readyState//获取Ajax状态码
onreadystatecgange 事件
当Ajax状态码发生变化时将自动触发该事件
xhr.onreadstatechange=function(){ }
通过判断Ajax的状态码来证明数据接收完成可以使用
// 创建Ajax对象 var xhr = new XMLHttpRequest() // 0:请求末初始化(还没有调用open()方法) console.log(xhr.readyState); // 配置Ajax对象 xhr.open('get', 'http://localhost:3000/readystade') // 1:请求已经建立,但是还没有发送(还没调用send()方法) console.log(xhr.readyState); xhr.onreadystatechange = function() { // * 2:代表已经发送 // * 3:请求正在处理中,通常响应中已经有部分数据可以用了 // * 4:响应已经完成,可以获取并使用服务器的响应了 console.log(xhr.readyState); // 对Ajax状态码进行判断,如果等于4证明数据接收完成 if (xhr.readyState == 4) { console.log(xhr.responseText); } } // 发送请求 xhr.send() ```
两种获取服务器端的响应方式的区别
区别 onload事件 onreadystatechange事件 是否兼容IE低版本 不兼容 兼容 是否需要判断Ajax状态码 不需要 需要 被调用次数 一次 多次 -
1.6 服务器端的数据格式
在真实项目中,服务器端大多数情况会把JSON对象作为响应数据的格式,当客户端拿到响应数据时,要将JSON数据和HTML字符串进行拼接,然后将拼接的结果展示在页面中
在http请求与响应的过程中,无论是请求参数还是响应内容,如果是对象类型,最终都会被转化为对象字符串进行传输
var responseText=JSON.parse(xhr.responseText)//将JSON字符串转化为JSON对象
//拼接字符串
var str = '<h2>' + responseData + '</h2>'
// 把这个字符串追加到body里面
document.body.innerHTML = str
1.7 请求参数传递
-
GET请求方式
使用Ajax发送get请求参数需要自己拼接的,然后把请求参数拼接到请求地址的后面// 拼接请求参数 var parmas = 'username=' + nameValue + '&age=' + ageValue // 告诉Ajax请求方式和请求地址 xhr.open('get', 'http://localhost:3000/get?' + parmas)
-
POST
请求参数自己拼接,必须设置post请求参数的数据格式的类型,把请求参数的字符串变量放在send里面发送
// 拼接请求参数 var parmas = 'username=' + nameValue + '&age=' + ageValue // 告诉Ajax请求方式和请求地址 xhr.open('post', 'http://localhost:3000/post') // post请求参数必须要设置的参数格式的类型 xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded') // 发送请求 xhr.send(parmas)
1.8 请求参数的格式
-
application/x-www-form-urlencoded
naem=zhangsan&age=20&sex=男
-
application/json
{name:'zhangsan',age:'20',sex:'男'}
在请求头中指定Content-Type属性的值是application/json,告诉服务器端当请求参数的格式是json。
JSON.stringify()//将json对象转化为json字符串
-
向服务器端传递json格式的请求参数
-
必须是用post请求方法
-
请求头的Content-Type的值必须是application/json
-
将json对象转化为json字符串
-
在服务器端响应的将urlencoded改为json
app.use(bodyparser.json({ extended: false }))
注意:get请求是不能提交json对象数据格式的,传统网站的表单提交也是不支持json对象数据格式
// 通过请求头告诉服务器端传递的参数是什么格式 xhr.setRequestHeader('Content-Type', 'application/json') // 发送请求,将json对象转化为json字符串 xhr.send(JSON.stringify({ name: 'zhansan', age: '21' }))
-
1.9 Ajax错误处理
Ajax状态码:表示Ajax请求的过程状态码,ajax对象返回的
Http状态码:表示请求的处理结果,是服务器端返回的
-
在网络畅通,服务器能接收请求,服务器返回的结果不是预期的结果
可以判断服务器端返回的状态码,分别进行处理。xhr.status获取http状态码
-
网络畅通,服务器端没有接收到请求,返回404状态码
检查请求地址是否错误
-
网络畅通,服务器端能接收请求,服务器端返回500状态码
-
当网络中端,请求无法发送服务器端
会触发xhr对象下面的onerror事件,在onerror事件处理函数中对错误进行处理
2.0 低版本IE浏览器的缓存问题
问题:
在低版本的IE浏览器中,Ajax请求有严重的缓存问题,即在请求地址不发生变化的情况下,只有第一次请求会真正发送到服务器端,后续的请求都会从浏览器缓存中获取结果,即使服务器端的数据更新了,客户端依然拿到的是缓存中的旧数据。
解决方案:在请求地址后面加请求参数,保证每一次请求中的请求参数的值不同
xhr.open('get','http://localhost:300?t='+Math.random())
2.1 同步异步概述
**同步 :**一个人同一时间只能做一件事,只有一件事情做完,才能做另外一件事情
落实到代码中,就是上一行代码执行完成后,才能执行下一行代码,即代码逐行执行
**异步:**一个人一件事情做了一半,转而去做其他事情,当其他事情做完以后,回头来继续做之前未完成的事情
落实到代码上,就是异步代码虽然需要花费时间去执行,但程序员不会等待异步代码执行完成后再继续执行后续代码,而是直接执行后续代码,当后续代码执行完成后再回头看异步代码是否返回结果,如果已有返回结果,再掉用事先准备好的回调函数处理异步代码执行的结果
Ajax里面的事件处理函数也是异步的。
2. Ajax的封装
2.1 封装Ajax的请求代码
获取响应头中返回的数据
xhr.responseHeader()//获取响应头数据,括号里面可以填写响应头当中的属性,就能获得对应的属性值
xhr.responseHeader('Content-Type')//获取服务器端返回的数据类型
对象的覆盖
Object.assign(defaults,optins)/前面一个对象的属性被后面一个对象的属性覆盖
问题:发送一次请求代码过多,发送多次请求代码沉余且重复
解决方案:将请求代码封装到函数中,发请求时调用函数即可
// 封装Ajax
function ajax(options) {
// 存储的是默认值
var defaults = {
type: 'get',
url: '',
data: {},
header: {
'Content-Type': 'applcation/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.substr(0, params.length - 1)
// 判断是get请求还是post请求,get请求就在url地址后面拼接参数
if (defaults.type == 'get') {
// 配置Ajax对象
xhr.open(defaults.type, defaults.url + '?' + params)
// 发送请求
xhr.send()
} else {
// 配置Ajax对象
xhr.open(defaults.type, defaults.url)
// 声明一个变量接收用户希望传递的请求参数的类型
var contentType = defaults.header['Content-Type']
// post请求参数必须设置请求参数的格式
xhr.setRequestHeader('Content-Type', contentType)
// 判断那种类型的数据格式
if (contentType == 'application/json') {
// 发送请求
xhr.send(JSON.stringify(defaults.data))
} else {
// 发送请求
xhr.send(params)
}
}
// 监听xhr对象下面的onload事件
xhr.onload = function() {
// 获取响应的数据类型
var contentType = xhr.getResponseHeader('Content-Type')
//服务器端返回的数据
var responseText = xhr.responseText
// 判断响应的数据类型
if (contentType.includes('application/json')) {
// 将json字符串转化为json对象
responseText = JSON.parse(responseText)
}
if (xhr.status != 200) {
// 请求失败
options.error(responseText, xhr)
} else {
// 请求成功
options.success(responseText)
}
}
}
ajax({
type: 'get',
url: 'http://localhost:3000/responseData',
data: {
name: '张三',
age: 20
},
header: {
'Content-Type': 'application/application/x-www-form-urlencoded'
},
success: function(data) {
console.log(data)
},
error: function(data, xhr) {
console.log(data);
console.log(xhr);
}
})
2.2 模板引擎
模板引擎的作用:使用模板引擎的模板语法,可以将数据和HTML,拼接起来
文档:https://aui.github.io/art-template/zh-cn
使用方法;
-
下载art-template模板引擎库文件并在HTML页面引入库文件
注意是绝对路径,前面加一个斜杠就是代表绝对路径
<script src="/js/template-web.js"></script>
- 准备art-template模板
要有一个id名字来区分模板,要在script写html标签,所以为了方便在里面写html语法,所以添加一个type属性,这样在里面的html语法会有高亮提示
<script id="tp1" type="text/html">
<h2></h2>
</script>
-
告诉模板引擎将哪一个模板和那一个数据进行拼接
第一个参数写那个模板要进行拼接就行写那个模板的id名字,第二个参数一个对象里面存储的数据是要在模板中展示的数据
var html = template('tp1',{username:'zhangsan',age:20})
- 通过模板语法告诉模板引擎,数据和html字符串要如何拼接
模板引擎的语法和node里面讲的一样的
<script type="text/html">
<div class="box">{{username}}</div>
</script>
-
将拼接好的html字符串添加到html页面中
使用DOM的方法找到html当中的容器,使用innerHTML的方法添加到里面
document.getElementById('container').innerHTML=html
2.2.1模板语法
如果数据携带HTML标签,默认情况下,模板引擎不会解析标签,会将其转义后原文输出
<h2>{{@ value}}</h2>//加一个@就可以原文输出,解析代码
2.2.3 条件判断
{{if 条件}} …… {{/if}}
{{if v1}} …… {{else if v1}} …… {{/if}}
2.2.4 循环
{{each 循环的数据}}
{{$index}} //循环的索引
{{$value}} //循环的值
{{/each}}
2.2.5 导入模板变量
导入变量可以使用JavaScript里面的方法或者变量
<div>$imports.dataFormat(time)</div> // 使用JavaScript里的变量或者方法
template.defaults.imports.变量名 = 变量值 //如果函数或变量在全局作用域下就不用这个方法也能访问,没有在全局作用域下就必须使用这个方法手动导入
3. FormData对象
3.1FormData对象的作用
- 模拟HTML表单,相当于HTML表单对象,自动将表单对象中的数据拼接成请求参数的格式
- 异步上传二进制的文件
3.2 FormData对象的使用
-
准备HTML,必须要有name属性,name属性的值作为请求参数的属性名
<!-- 创建普通的html表单 --> <form id="form"> <input type="text" name="username"> <input type="password" name="password"> <input type="button" id="btn" value="提交"> </form>
-
将HTML表单转化为formData对象
-
需要通过DOM方法获取表单
-
将获取到的表单传递到FormData函数中
-
如果不传递表单到FormData函数中就是创建了一个空的formData表单对象
// 获取按钮 var btn = document.getElementById('btn') // 获取表单 var form = document.getElementById('form'); btn.onclick = function() { alert(1) } // 给按钮添加点击事件 btn.onclick = function() { // 将普通的表单转化为表单对象 var formData = new FormData(form)
-
-
提交表单对象,直接放在send()方法中
// 创建Ajax对象 var xhr = new XMLHttpRequest() // 配置Ajax对象 xhr.open('post', 'http://localhost:3000/formdata') // 发送请求 xhr.send(formData) // 监听xhr下面的onload事件获取服务器端响应给客户端的数据 xhr.onload = function() { // 判断http的状态码 if (xhr.status == 200) { console.log(xhr.responseText); } } }
注意:formData对方不能使用get方法提交,body-paser不能处理客户端传递过来的FormData对象,所以要用fomidable这个第三方模块
3.3 FormData对象的实例方法
-
获取表单对象当中属性的值
formData.get('key')//括号里面填写表单对象当中的属性,也就是name名字,就能获取表单的值,注意要加引号
-
设置表单对象当中属性的值
如果设置的表单属性存在就是替换原有的表单属性的值,如果设置的表单属性不存在将会创建这个表单属性
formData.set('key','value')//第一个参数是表单对象当中的属性,第二个参数是要设置成的属性值
-
删除表单对象中的属性值
```js
formData.delete('key')//括号里面直接写要删除的属性值的属性
```
- 向表单对象中追加属性值
注意:set方法与append方法的区别是,在属性名已经存在的情况下set会覆盖已有的属性值,append会保留两个值,服务器端如果没有经过特殊的设置,如果有两个同样的属性,他会接收最后一个的formData.append('key','vaule')
3.4 FormData 二进制文件上传
文件上传只能用post请求
// 获取上传文件控件
var file = document.getElementById('file')
// 为上传文件控件添加onchange事件
// 在用户选择文件的时候触发
file.onchange = function() {
// 创建一个空的表单FormData对象
var formData = new FormData()
// 将用户选择的文件追加到formData表单对象中
formData.append('attrName', this.files[0])
// 创建Ajax对象
var xhr = new XMLHttpRequest()
// 配置对象
xhr.open('post', 'http://localhost:3000/upload')
// 发送请求
xhr.send(formData)
// 获取服务器端响应的内容
xhr.onload = function() {
if (xhr.status == 200) {
console.log(xhr.responseText);
}
}
}
3.4.1 FormData文件上传进度展示
- 在xhr下面有一个upload对象,保存了一些和上传相关的事件
- 在upload对象中有一个onprogress事件,当事件被触发的时候,系统会给我们传递事件对象
- ev.loaded 文件已经上传了多少,ev.total 上传文件的总大小
- 用上传了多少除以上传总大小乘以100加一个百分号
- 如何赋值给进度条的宽度和进度条的内容
// 在文件上传的过程中持续触发
xhr.upload.onprogress=function(ev){
// ev.loaded 文件已经上传了多少
// ev.total 上传文件的总大小
var result=(ev.loaded / ev.total) * 100 + '%'
//把结果赋值给div的宽度
bar.style.width = result
//把结果赋值给div的内容
bar.innerHTML=result
}
3.4.2 FormData文件上传图片即使预览
在外面将图片上传到服务器端以后,服务器端通常都会将图片地址作为响应数据传递到客户端,客户端可以从响应数据中获取图片地址,然后将图片显示在页面中。
// 获取服务器端响应的内容
xhr.onload = function() {
if (xhr.status == 200) {
//服务器端响应的json字符串,所以要把他转化为json对象
result = JSON.parse(xhr.responseText)
// 动态创建img
var img = document.createElement('img')
// 设置图片的src属性
img.src = result.path
// 在img标签有一个onload事件,当图片加载完触发
img.onload = function() {
//把图片追加在页面当中
box.appendChild(img)
}
}
}
4. 同源政策
4.1 什么是同源
如果两个页面拥有相同的协议、域名、端口,那么这两个页面就属于同一个源,其中只要有一个不相同,就不是同源
4.2 Ajax 请求限制
Ajax只能向自己的服务器发送请求,比如现在有一个A网站,有一个B网站,A网站中的HTML文件只能向A网站服务器发送Ajax请求,B网站中的HTML文件只能向B网站中发送Ajax请求,但是A网站是不能向B网站发送Ajax请求的,同理,B网站也不能向A网站发送请求Ajax请求的
4.3 同源政策的目的
-
同源政策是为了保证用户信息的安全,防止恶意的网站窃取数据,最初的同源政策是指A网站在客户端设置的Cookie,B网站是不能访问的。
-
随着互联网的发展,同源政策越来越严格,在不同源的情况下,其中有一项规定就是无法向非同源的地址发送Ajax请求,如果请求,浏览器就会报错。(请求是能发送出去的,但是浏览器狙击接收响应)
4.4 使用JSONP解决同源限制问题
jsonp是json with padding 的缩写,他不属于Ajax请求,但他可以模拟Ajax请求
-
将不同源的服务器端请求地址写在script标签的src属性中(例如加载线上的jQuery)
<script src="https://odn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
-
服务器端响应数据必须是一个函数的调用,真正要发送给客户端的数据需要作为函数调用的参数
cosnt data = 'fn({name: "张三", age: "20"})' res.send(data)
-
在客户端全局作用域下定义函数fn
function fn (data){ }
-
在函数内部对服务器端返回的数据进行处理
function fn (data){ console.log(data)}
4.4.1 JSONP 代码优化
- 客户端需要将函数名称传递到服务器端
- 将script请求的发送变成动态请求
<button id="btn">发送</button>
<script>
function fn(data) {
console.log(data);
}
// 获取按钮
var btn = document.getElementById('btn')
btn.onclick = function() {
// 动态创建script标签
var script = document.createElement('script')
// 给script标签添加src属性,把函数名称作为参数发送给服务器端
script.src = "http://localhost:3001/test?callback=fn"
// 把script标签添加到body里面
document.body.appendChild(script)
// 给script标签添加onload事件
script.onload = function() {
// script标签加载完内容以后就把他删除
document.body.removeChild(script)
}
}
</script>
-
封装jsonp函数,方便发送请求
function jsonp(options) { // 动态创建script标签 var script = document.createElement('script') // 拼接字符串 var params = '' for (var att in options.data) { params += '&' + att + '=' + options.data[att] } // 生成随机的函数名字 var fnName = 'myJonp' + Math.random().toString().replace('.', '') // 声明函数把他给window下的属性,这样就是全局函数了 window[fnName] = options.success // 给script标签添加src属性 script.src = options.url + '?callback=' + fnName + params // 把script标签添加到body里面 document.body.appendChild(script) // 给script标签添加onload事件 script.onload = function() { // script标签加载完内容以后就把他删除 document.body.removeChild(script) } } //调用 jsonp({ //地址 url: "http://localhost:3001/test", //参数 data: { naem: 'lisi', age: 30 }, //服务器端返回的数据 success: function(data) { console.log(123) console.log(data) } })
4.5 CORS 跨域资源共享
COSR:全称为Cross-origin resource sharing , 即跨域资源共享,它允许浏览器跨域服务器发送Ajax请求,克服Ajax只能同源使用的限制。
只需要在服务器端拦截所有的请求,设置两个响应头,客户端正常操作就行
app.use((req,res,next)=>{
//允许那些客户端访问,*代表所有客户端都可以
res.header('Access-Control-Allow-Origin','*')
//允许客户端使用那些请求方式访问
res.header('Access-Control-Allow-Origin','get,post')
next()
})
4.6 服务器端解决访问非同源方案
-
使用express框架下面的request这个第三方模块访问其他的服务器端
-
使用npm install request下载
const request = require('request') app.get('/server',(req,res)=>{ //第一个参数是服务器端访问其他服务器端的地址,第二个是回调函数 //err是保存错误对象,response是保存响应数据的一些信息,body是响应的数据 request('http:localhost:3001/cross',(err,response,body)=>{ res.send(body) }) })
4.7 withCredentials属性
-
在使用Ajax技术发跨域请求时,默认情况下不会再请求中携带cookie信息
-
withCredentials:指定再涉及跨域请求时,是否携带cookie信息,默认值为false
xhr.withCredentials = true
-
Access-Control-Allow-Credentials:true允许客户端发送请求时携带cookie
res.header('Access-Control-Allow-Credentials',true)
-
5. 使用jQuery发送ajax()
作用:发送Ajax请求
$.ajax()的常用参数
如果想发送json对象请求参数,在外面声明一个变量存储json对象,在data:里面写JSON.stringify()方法转换成json字符串
$.ajax({
type:'get',//请求方式
url:'http://www.example.com',//请求地址
data:{name;'zs',age:20},//请求参数
contentType:'application/x-www-form-urlencoded',//向服务器端传递请求参数的格式
beforeSend:function () {//允许在发送请求之前做的事情,这个事情会在发送请求之前调用
return false
},
success:function (response) {},//请求发送成功执行,response这个形参对应服务器端返回的数据,方法内部会自动将json字符串转换为json对象
error:function (xhr) {}//在请求失败的时候会进入这个函数,获得错误信息
})
5.1 serialize方法
作用:将表单中的数据自动拼接成字符串类型的参数
//表单提交的时候触发这个事件
$('#form').on('submit',function(){
//调用serialize方法自动拼接字符串类型的参数
var params = $('form').serialize()
//阻止表单默认提交的行为
return false
})
5.2 serializeArray方法
- 返回一个数组,数组里面是对象,有多少个表单控件就有多少个对象
- 对象中有两个属性,name和value
[{name:'username,就是表单中的name属性值',value:'用户输入的内容'}]
封装一个函数将表单中用户输入的内容转换为对象类型
function serializeObject(){
//处理结果对象
var result = {}
//把用户输入的字符串转换成[{}]的格式
var params = obj.serializeArray()
//循环数组
$.each(params,function(){
result[value,name] = value.value
//将处理的结果返回到函数外部
return result
})
}
5.3 使用$.ajax()方法发送jsonp请求
$.ajax({
url: '/jsonp',//请求的地址
dataType:'jsonp',//代表现在要发送的是jsonp请求
jsonp:'cd',//修改callback参数名称
jsoncallback:'fnName'//指定函数名称
success:function(response){
console.log(response)//服务器端返回的结果
}
})
5.4 . g e t ( ) 、 .get()、 .get()、.post()方法概述
作用: . g e t ( ) 方 法 是 发 送 g e t 请 求 的 , .get()方法是发送get请求的, .get()方法是发送get请求的,.post()方法是发送post请求的
第一个参数是请求地址,第二个参数是像服务器端发送的请求参数可以是对象也可以是字符串可选参数,第三个参数是回调函数,请求成功会调用这个函数并且将服务器端返回的数据作为参数传递给我们
$.get('http://loaclhost:3000/get',{naem:'zs',age:18},function(response){
})
$.post('http://loaclhost:3000/get',{naem:'zs',age:18},function(response){
})
5.5 jQuery中Ajax全局事件
ajaxStart 当请求开始发送时触发
ajaxComplete 当请求完成时触发
//需要绑定在document上
$(document).on('ajaxStart',function(){ })
$(document).on('ajaxComplete',function(){ })
6. RESTful 风格的API
服务器端的路由设置
//获取用户列表信息
app.get('/users',(req,res=>{
res.send('当前是获取用户列表信息的路由')
}))
//获取某一个用户具体信息
app.get('/users/:id',(req,res=>{
const id = req.params.id
res.send('当前是获取id为${id}用户信息的路由')
}))
//删除某一个用户
app.put('/users/:id',(req,res=>{
const id = req.params.id
res.send('当前是修改id为${id}用户信息的路由')
}))
//修改某一个用户
app.delete('/users/:id',(req,res=>{
const id = req.params.id
res.send('当前是删除id为${id}用户信息的路由')
}))
7.XML 基础
7.1 XML是什么
XML的全称是extexsible markup language , 代表可扩展标记语言,它的作用是传输和存储数据。
7.2 XML DOM
XML DOM 即XML文档对象模型,是w3c组织定义的一套XML对象的API。浏览器会将XML文档解析成文档对象模型。
客户端代码示例
<button id="btn">发送请求</button>
<div id="container"></div>
<script>
// 获取按钮
var btn = document.getElementById('btn')
var container = document.getElementById('container')
btn.onclick = function() {
var xhr = new XMLHttpRequest()
xhr.open('get', 'http://localhost:3000/xml')
xhr.send()
xhr.onload = function() {
//获取服务器端响应的xml数据
// console.log(xhr.responseXML);
//用一个变量接收
var xmlDocument = xhr.responseXML
// 获取xml里面标签的值
var title = xmlDocument.getElementsByTagName('title')[0].innerHTML
container.innerHTML = title
}
}
</script>
服务器端代码示例
app.get('/xml', (req, res) => {
//指定响应头是xml数据
res.header('content-type', 'text/xml')
res.send('<message><title>消息标题</title><content>消息内容</content></message>')
})
8. Git基础
8.1 版本管理
8.1.1 什么是版本管理
版本管理是一种记录文件变化的方式,以便将来查阅特定版本的文件内容
8.1.2 人为维护文档版本的问题
- 文档数量多且命名不清晰导致文档版本混乱
- 每次编辑文档需要复制,不方便
- 多人同时编辑同一个文档,容易产生覆盖
8.1.3 Git是什么
Git是一个版本管理控制系统(缩写VCS),它可以在任何时间点,将文档的状态作为更新记录保存起来,也可以在任何时间点,将更新纪录恢复回来。
8.1.4 Git的基本工作流程
git仓库 | 暂存区 | 工作目录 |
---|---|---|
用于存放提交记录 | 临时存放被修改文件 | 被Git管理的项目目录 |
8.2 Git的基本使用
8.2.1 Git使用前配置
在git使用前,需要告诉git你是谁,在向git仓库中提交时需要用到
1. 配置提交人姓名: ```git config --global user.name 提交人姓名```
-
配置提交人邮箱: ```git config --global user.email 提交人邮箱``
-
查看git配置信息:
git config --list
注意:
-
如果要对配置信息进行修改,重复上述命令即可
2. 配置只需要执行一次
8.2.2提交步骤
git init
初始化git仓库git status
查看文件状态git add 文件列表
追踪文件(把文件放在暂存区)git commit -m 提交信息
向仓库中提交代码git log
查看提交记录
8.2.3 撤销
- 用户暂存区中的文件覆盖工作目录中的文件:
git checkout 文件
- 用户暂存区中删除,删除过后在暂存盘里没有了。但是在工作目录还是会有:
git rm --cached 文件
- 将git仓库中指定的更新记录恢复出来,并且覆盖暂存区和工作目录:
git reset --hard 文件的commit的值
8.3 分支
为了便于理解,暂时理解为分支就是当前工作目录中的代码副本,使用分支,可以让我们从开发主线上分离出来,以免影响开发主线。
8.3.1 分支细分
- 主分支(master):第一次向git仓库提交更新记录时自动产生的一个分支。
- 开发分支,(develop):作为开发的分支,基于master分支创建
- 功能分支(feature):作为开发具体功能的分支基于开发分支创建
功能分支—>开发分支—>主分支
8.3.2 分支命令
git branch
查看分支git branch 分支名称
创建分支git checkout 分支名称
切换分支 切换分支前记得要提交分支或暂时保存更改git merge 来源分支
合并分支 比如要把开发分支合并到主分支,就业切换到主分支在使用命令合并git branch -d 分支名称
删除分支(分支被合并后才允许被删除)(-D强制删除)要想强制删除就使用大写的D删除
8.3.3 暂时保存更改
在git中,可以暂时提取分支上所有的改动并存储,让开发人员得到一个干净的工作副本,临时转向其他的工作
使用场景:分支临时切换
- 存储临时改动:
git stash
- 恢复改动:
git stash pop
8.4 Github
在版本控制系统中,大约90%的操作都是在本地仓库进行的:暂存、提交、查看状态或者历史记录等待。除此之外,如果仅仅只有你一个人在这个项目工作,就不需要设置一个远程仓库。
当需要和团队共享数据时,设置一个远程仓库,你可以把它想像成一个”文件管理服务器“,利用这个服务器可以与开发团队的其他成员进行数据交换。
8.4.1 注册GitHub
- 访问GitHub首页,点击Sing up 连接。(注册)
8.4.2 多人协作开发流程
-
A在自己的计算机中创建本地仓库
-
A在GitHub中创建远程仓库
-
A将本地仓库进行推送到远程仓库
-
B克隆远程仓库到本地进行开发
-
A要给B设置权限,使他可以向远程仓库提交内容
-
B将本地仓库中开发的内容推送到远程仓库
-
A将远程仓库中的最新内容拉去到本地
A ————————> 远程仓库 <———————— B
<———————— ————————>
8.4.3 本地仓库推送到GitHub远程仓库
- git push 远程仓库的地址 分支名称
- git push 远程仓库地址别名 分支名称
- git push -u 远程仓库地址别名 分支名称 -u 记住推送地址及分支,下次推送只需要输入git push即可
- git remote add 远程仓库地址别名(origin一般取这个名字) 远程仓库的地址
8.4.4 克隆仓库
克隆远端数据仓库到本地:git clone 仓库地址
8.4.5 拉取远程仓库最新的版本
拉取远程仓库中最新的版本:git pull 远程仓库地址或地址别名 分支名称
拉取和克隆比较
拉取是在本地已经有了的情况下和远程仓库进行比较,拉去最新版本,克隆是在没有本地仓库的情况下进行,只需要在第一次操作项目的情况下用到,在后面的操作中,如果需要获取远程仓库的最新版本,只需要拉取就行。
本地的版本不能比远程仓库的版本低,如果要进行提交,必须拉取最新版本,在进行提交。
8.4.6 解决冲突
在多人同时开发一个项目时,如果两个人修改了同一个文件的同一个地方,就会法发生冲突,冲突需要人为解决。
8.4.7 ssh免登入
生成密钥:ssh-keygen
1. 在项目文件打开git Bash Here ,输入就可以生成密钥
2. 其实就是俩个文件,私钥是 id_rsa文件,公钥是 id_rsa.pub文件。
私钥保存在自己电脑当中,
公钥保存在GitHub服务器中。
在C盘中找到公钥文件,打开复制里面的代码,登入GitHub点击头像点击setting设置,在点击SSH and GPG keys 在点击new SSH key 把代码粘贴,然后点击 Add SSH key
密钥存储目录:C:\User\用户.ssh
8.4.8 GIT忽略清单
将不需要被git管理的文件名字添加到此文件中,在执行git命令的时候,git就会忽略这些文件
git忽略清单文件名称:.gitignore
直接在文件里面写文件夹或者文件的名字
将工作目录中的全部文件添加到暂存区:git add .
8.4.9 为远程仓库添加详细说明
在项目文件里面添加一个 readme.md 文件 在文件中添加一些说明
这个文件是使用marckdown语法编写的