AJAX 是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术。
如何发送请求
常用的五种方法
- 用
form
表单可以发发送GET和POST请求请求,但是会刷新页面或新开页面
<body>
<form action="xxx" method=get> //get或post
<input type="password" name="password">
<input type="sumbit">
</form>
<body>
查看get/post的路径到开发者工具看,记得点view source
才能查看路径。
- 用
a
标签可以发get请求,但是也会刷新页面或新开页面 - 用
img
可以发 get 请求,但是只能以图片的形式展示 - 用
link
可以发 get 请求,但是只能以CSS、favicon 的形式展示,而且必须放到页面里面 - 用
script
可以发 get 请求,但是只能以脚本的形式运行
上面的方法虽然都是可以发起请求,但是太限制了。那么,有没有什么方式可以实现:
- get、post、put、delete 请求都行
- 想以什么形式展示就以什么形式展示
有的,就是XMLHttpRequest
API
这个API是IE 5 率先在 JS 中引入 ActiveX 对象(API),使得 JS 可以直接发起 HTTP 请求。
随后 Mozilla、 Safari、 Opera 也跟进了,取名XMLHttpRequest
,并被纳入 W3C 规范.
XMLHttpRequest
是一个函数,而且是一个构造函数,它是window下的一个全局对象
AJAX(async javascript and XML)
Jesse James Garrett 讲如下技术取名叫做 AJAX:异步的 JavaScript 和 XML.
使用 XMLHttpRequest对象的open方法发送HTTP请求
myButton=addEventListener('click',(e)=>{
let request=new XMLHttpRequest() //声明XMLHttpRequest对象
request.open('GET','/xxx') //初始化request
request.send()
})
这里有个有趣的点,就是即使把open()
的method参数换成fuck
,我们一样可以发起请求,但服务器不接收~
服务器返回 XML 格式的字符串
这种格式应该是已经失传了的,但是我们可以尝试做一下
} else if(path==='/xxx'){
response.statusCode=200
response,setHeader('Content-Type','text/xml')
response.write(`
<?xml version="1.0" encoding="UTF-8"?>
<note>
<to>Tove</to>
<from>phoebe</from>
<heading>Reminder</heading>
<body>hello,World!</body>
</note>
`)
response.end()
这种格式现在很少前端会再使用了,原因是:
- XML文件庞大,文件格式复杂,传输占带宽;
- 服务器端和客户端都需要花费大量代码来解析XML,导致服务器端和客户端代码变得异常复杂且不易维护;
- 客户端不同浏览器之间解析XML的方式不一致,需要重复编写很多代码;
- 服务器端和客户端解析XML花费较多的资源和时间。
XMLHttpRequest实例的属性
readyState
这个属性存有 XMLHttpRequest 的状态信息。
一般我们需要熟记状态4即可。
readystatechange
每当 readyState 属性改变时,就会触发 onreadystatechange 事件,调用该函数。
responseText
这个属性返回从服务器接收到的字符串,它包含对文本的请求的响应,如果请求不成功或尚未发送,则返回null。
JSON(数据交换语言)
JavaScript | Json |
---|---|
undefined | 没有undefined |
null | null |
['a','b'] | ["a","b"] |
function fn(){} | 没有function |
{name:'phoebe'} | {"name":"phoebe"} |
'phoebe' | "phoebe" |
var a={} a.self=a | 搞不定(没有变量) |
{--proto--} | 没有原型链 |
JavaScript和Json的区别
JavaScript | Json |
---|---|
undefined | 没有undefined |
null | null |
['a','b'] | ["a","b"] |
function fn(){} | 没有function |
{name:'phoebe'} | {"name":"phoebe"} |
'phoebe' | "phoebe" |
var a={} a.self=a | 搞不定(没有变量) |
{--proto--} | 没有原型链 |
- JSON没有引进JavaScript的
function
和undefined
- JSON的字符串首尾必须是
""
} else if(path==='/xxx'){
response.statusCode=200
response,setHeader('Content-Type','text/xml')
response.write(`
{
"note":{
"to":"小谷",
"from":"方方",
"heading":"打招呼",
"content":"hi"
}
}
`)
//注意!这是返回一段字符串,不是返回对象。这是一段符合json对象语法的字符串
myButton=addEventListener('click',(e)=>{
let request=new XMLHttpRequest() //声明XMLHttpRequest对象
request.open('GET','/xxx')
request.send()
request.onreadystatechange=()=>{
if (request.readyState===4){
console.log('请求响应都完毕了')
if (request.status>=200&&request.status<300) {
let string=request.responseText
//把符合JSON的语法的字符串转换成JS对应的值
let object=window.JSON.pare(string)
//JSON.parse 是浏览器提供的
}else if(request.status>=400){
console.log('说明请求失败了')
}
}
}
})
同源政策
浏览器必须保证只有协议+端口+域名一模一样才允许发 AJAX 请求
例:
http://baidu.com
可以向http://www.baidu.com
发 AJAX 请求吗? no
http://baidu.com:80
可以向http://baidu.com:81
发 AJAX 请求吗? no
AJAX
语法
let request = new XMLHttpRequest()
request.open('get', 'http://jack.com:8002/xxx') // 配置request
request.send()
request.onreadystatechange = ()=>{
if(request.readyState === 4){
if(request.status >= 200 && request.status < 300){
let string = request.responseText
// 把符合 JSON 语法的字符串转换成 JS 对应的值
let object = window.JSON.parse(string)
// JSON.parse 是浏览器提供的
}
}
}
})
使用AJAX实现两个网站之间的交流(跨站资源共享)
只需在后台代码使用CORS(cross-origin resource sharing) 跨域请求
response.setHeader('Access-Control-Allow-Origin','http://frank.com:8001')
//后台代码
} else if(path==='/xxx'){
response.statusCode=200
response,setHeader('Content-Type','text/json;charset=utf-8')
response.setHeader('Access-Control-Allow-Origin','http://frank.com:8001') //响应头。CORS 跨域
response.write(`
{
"note":{
"to":"小谷",
"from":"方方",
"heading":"打招呼",
"content":"hi"
}
}
`)//注意!这是返回一段字符串,不是返回对象。这是一段符合json对象语法的字符串
response.end()
若是想要实现所有网站都可访问,只需
`response.setHeader('Access-Control-Allow-Origin','http://frank.com:8001',*)`
//在末尾加*