同步交互和异步交互
所谓同步交互就是指当客户端向服务端和数据库发送数据之后,若要发送下一个请求需要等待服务端和数据库的响应结果。这就好比数据结构中的队列,一个执行完毕在执行下一个。也类似一些面向过程语言的代码执行顺序。
而异步交互就是指客户端向服务端发送数据之后,无需等待服务端和数据库的响应结果,就可以发送下一个请求。
如下图说明了同步交互和异步交互的区别:
异步交互与同步交互的劣势:
- 破坏了浏览器的前进和后退机制
- 后面逻辑依靠前面逻辑时,可能会出现问题
- Ajax 对搜索引擎支持较弱
- 容易引起 web 安全问题
Ajax 是什么
Ajax 全称 “Asynchronous JavaScript and XML” 被译为:异步 JavaScript 和 XML。
虽然 Ajax 中的 x 代表 XML,但是现在 JSON 的诸多优势 JSON 的使用比 XML 更加普遍。
JSON 和 XML 都用于在 Ajax 模型中封装数据
Ajax 涉及的技术
Ajax 并不是一个新技术,而是多个技术的整合:
- HTML
- CSS
- JavaScript
- DOM
- XML
- XMLHttpRequest 对象
XMLHttpRequest
是 Ajax 的核心。
XMLHttpRequest
对象提供了在客户端和服务端传输数据的功能,XMLHttpRequest
对象提供了通过 URL 方式来获取数据,只更新网页的一部分数据。
实现 Ajax 的步骤
- 创建 Ajax 核心对象(XMLHttpRequest)
- 通过 Ajax 核心对象的
open()
方法建立与服务端的链接 - 构建请求的数据内容,通过核心对象的
send()
方法发送给服务端 - 通过核心对象提供的
onreadystatechange
事件,监听服务端的通信状态 - 接受处理服务端响应的结果
- 将结果更新到页面
创建 XMLHttpRequest 对象
由于创建 Ajax 对象的方式在浏览器之间存在不同的情况所以需要编写一个自定义 js 文件来实现浏览器兼容。 主要兼容的是 IE 浏览器。
在其他非 IE 的主流浏览器中创建 Ajax 对象的方法为:new XMLHttpRequest()
,
而在 IE 中又分为两种情况:
IE7 版本:new ActiveXObject("Msxml2.XMLHTTP")
IE6 及以下版本:new ActiveXObject("Microsoft.XMLHTTP")
Tools.js 文件如下:
Object.defineProperty(window, "createXMLHttpRequest", {
value: function () {
var httpRequest;
// 如果是非IE浏览器
if (window.XMLHttpRequest) {
httpRequest = new XMLHttpRequest();
}
// 如果是 IE 浏览器
else if (window.ActiveXObject) {
try {
// IE 7+
httpRequest = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
// IE 6-
httpRequest = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e) {}
}
}
return httpRequest;
},
});
在 HTML 页面中引入之前创建的 Tools.js 文件,然后调用 createXMLHttpRequest
方法进行创建即可。
如下代码:
var ajax = createXMLHttpRequest();
console.log(ajax);
返回的结果为一个 XMLHttpRequest
对象。
实现 Ajax 异步交互
接下来模拟发请求和获取响应数据的过程,还是依照上面的过程
- 创建
XHR
对象 - 调用
XHR
对象的open()
方法 - 调用
XHR
对象的send()
方法 - 调用
onreadystatechange
监听服务端通信状态 - 使用
readyState
属性判断服务端响应状态
open()
方法
open()
方法语法结构:
open(method, url[, async, user, password])
参数说明:
- method:请求方法,get、post、put、delete 等
- url:发送请求的 url
- async:是否异步交互
- user:用户名用于认证用途
- password:用户密码
send()
方法
在调用 send()
方法时,用于发送数据,默认为异步发送,发送后立即返回;
若为同步发送等待响应后返回。send
方法不传入参数代表不发送数据,当请求方式为 get
、head
时需要将主体设置为 null
。
readyState
属性
XHR
对象的 readyState
属性返回值:
- 0:XHR 被初始化,未调用 open 方法
- 1:XHR 调用 open
- 2:XHR 调用 send
- 3:下载中
- 4:下载完成
当 readyState
属性放在 open()
之下和 send()
之下时,返回的结果都为 2,3,4;
当放在 open()
之上 createXMLHttpRequest
之下时,返回 1,2,3,4
responseText
属性
XHR
对象的 responseText
属性接受服务端对该请求的响应结果。
status
属性
XHR
的 status
属性返回当前服务端状态响应码,常见的状态响应码如下:
- 200:请求成功
- 304:请求的资源伪未变化(没有改动)
- 404:服务器端地址未找到
对于对于上面写法如果对 open()
方法写入的服务端地址不正确则返回一个 404 报错,如果请求正确则返回 200。
get 请求方式
通过表单提交的数据,如果是 get
方式提交的数据会在地址栏上进行显示。
在 Ajax 提交方式中如果使用 get
或者 head
方式提交数据时,send
方法中只能写入 null
。
若要提交数据需要在对服务器的请求网址中输入相应的参数。如下代码所示:
<body>
<button id="btn">按钮</button>
<script src="./myTools.js"></script>
<script>
var btn = document.getElementById("btn");
btn.addEventListener("click", function () {
var xhr = createXMLHttpRequest();
xhr.open(
"get",
"http://localhost:63343/ricardo/Ajax/%E4%BB%A3%E7%A0%81/%E6%B5%8B%E8%AF%95xhr.html?_ijt=22k61vqrrkstdjmlf6eo3ug8iu?user=hello#"
);
xhr.send(null);
});
</script>
</body>
get 请求方式会直接在地址栏中追加数据。
POST 请求方式
在使用 POST 发送请求时,可以写在 XHR
中的 send()
方法中。
如下代码所示:
<body>
<button id="btn">按钮</button>
<script src="./myTools.js"></script>
<script>
var btn = document.getElementById("btn");
btn.addEventListener("click", function () {
var xhr = createXMLHttpRequest();
xhr.open(
"post",
"http://localhost:63343/ricardo/Ajax/%E4%BB%A3%E7%A0%81/%E6%B5%8B%E8%AF%95xhr.html?_ijt=3b3upkr00lb4gtto8n5tb2o21u"
);
xhr.send("user=zhang&pwd=1234");
});
</script>
</body>
结果:
在使用 POST
方式发送请求之前需要先使用 XHR
对象的 setRequestHeader()
方法设置请求头部信息。
如下代码所示:
var btn = document.getElementById("btn");
btn.addEventListener("click", function () {
var xhr = createXMLHttpRequest();
xhr.open(
"post",
"http://localhost:63343/ricardo/Ajax/%E4%BB%A3%E7%A0%81/%E6%B5%8B%E8%AF%95xhr.html?_ijt=3b3upkr00lb4gtto8n5tb2o21u"
);
// 使用 POST 请求设置请求头部信息
xhr.setRequestHeader("Content-Type", "application/x-www-for-urlencoded");
xhr.send("user=zhang&pwd=1234");
});
当设置了头部信息之后,在浏览器的抓包工具中发现格式为:
server.js-创建一个自己的服务
var http = require('http')
var fs = require('fs')
var url = require('url')
var port = process.argv[2]
if(!port){
console.log('请指定端口号好不啦?\nnode server.js 8888 这样不会吗?')
process.exit(1)
}
var server = http.createServer(function(request, response){
var parsedUrl = url.parse(request.url, true)
var pathWithQuery = request.url
var queryString = ''
if(pathWithQuery.indexOf('?') >= 0){ queryString = pathWithQuery.substring(pathWithQuery.indexOf('?')) }
var path = parsedUrl.pathname
var query = parsedUrl.query
var method = request.method
/******** 从这里开始看,上面不要看 ************/
console.log('有个傻子发请求过来啦!路径(带查询参数)为:' + pathWithQuery)
if(path === '/'){
response.statusCode = 200
response.setHeader('Content-Type', 'text/html;charset=utf-8')
response.write(`二哈`)
response.end()
} else if(path === '/x'){
response.statusCode = 200
response.setHeader('Content-Type', 'text/css;charset=utf-8')
response.write(`body{color: red;}`)
response.end()
} else {
response.statusCode = 404
response.setHeader('Content-Type', 'text/html;charset=utf-8')
response.write(`你输入的路径不存在对应的内容`)
response.end()
}
/******** 代码结束,下面不要看 ************/
})
server.listen(port)
console.log('监听 ' + port + ' 成功\n请用在空中转体720度然后用电饭煲打开 http://localhost:' + port)
- 使用node.server.js 8888启动
- 添加index.html和main.js两个路由
总结
- const request = new XMLHttpRequest
- request.open("","")
- request.onload()
- request.onerror()
- request.onreadystatechange()
- request.send()
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!