文章目录
一、手写一个简易的ajax
function ajax(url) {
const p = new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest()
xhr.open('GET', url, true)
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
resolve(
JSON.parse(xhr.responseText)
)
} else if (xhr.status === 404 ) {
reject(new Error('404 not found'))
}
}
}
xhr.send(null)
})
return p
}
const url = './data/test.json'
ajax(url)
.then(res => console.log(res))
.catch(err => console.error(err))
二、跨域的常用实现方法
- JSONP
- CORS
三、XMLHttpRequest (knowledge point)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>ajax 演示</title>
</head>
<body>
<p>一段文字 1</p>
<script src="./ajax.js"></script>
</body>
</html>
{
"name": "zhangsan"
}
*** get 请求
// 初始化一个实例
const xhr = new XMLHttpRequest()
xhr.open("GET","/data/test.json",true)
xhr.onreadystatechange = function(){
// 这里的函数异步执行 , 可参考之前的异步模块
if(xhr.readyState === 4){
if(xhr.status === 200){
// console.log(
// JSON.parse(xhr.responseText)
// )
alter(xhr.responseText)
}else if (xhr.status === 404) {
console.log('404 not found')
}
}
}
xhr.send(null)
*** post 请求
// 初始化一个实例
const xhr = new XMLHttpRequest()
xhr.open("POST","/login",true)
xhr.onreadystatechange = function(){
// 这里的函数异步执行 , 可参考之前的异步模块
if(xhr.readyState === 4){
if(xhr.status === 200){
// console.log(
// JSON.parse(xhr.responseText)
// )
alter(xhr.responseText)
}else {
console.log('其他情况')
}
}
}
const postData = {
username : 'zhangsan',
password : 'xx'
}
xhr.send(JSON.stringify(postData))
== 注释==
- open :open 是准备数据,true : 异步请求 ,false : 同步请求
- onreadystatechange :onreadystatechange 这个 回调函数 和 img.onload = function(){} 以及img.onerror = function(){}差不多, 回调函数 里面是接受数据的
- 状态码 :记住除了null 以外 都是用 ===
- JSON.parse : 转换成JSON 格式
- send(): get 请求 不用发送数据 ,直接发送null 就好咯 ;post 需要发送数据(要字符串 ,不可以直接是JSON)
- JSON.stringify : 变成JSON 字符串
四、状态值 & 状态码 (knowledge point)
1、readyState
0:(未)初始化,XMLHttpRequest对象还没有完成初始化,还没有调用send()方法
1:载入,XMLHttpRequest对象开始发送请求 ,已调用 send()方法
2:载入完成,XMLHttpRequest对象的请求发送完成 , send()方法执行完成 ,已经接收到全部响应内容
3:解析、交互,XMLHttpRequest对象开始读取解析服务器的响应内容
4:完成,XMLHttpRequest对象读取服务器响应结束,解析完成,可以在客户端调用
- 只有在4 的情况下才可以 拿到 xml. responseText
2、status
1xx:信息响应类,表示接收到请求并且继续处理
2xx:处理成功响应类 , 即成功处理请求,表示动作被成功接收、理解和接受
3xx:重定向响应类,为了完成指定的动作,必须接受进一步处理 ,服务器返回后,浏览器会自己直接跳转
4xx:客户端错误,客户请求包含语法错误或者是不能正确执行
5xx:服务端错误,服务器不能正确执行一个正确的请求
200——交易成功
301——代表永久性转移 ,访问b 网址,服务器返回了a地址 ,浏览器永远会主动直接跳转到a(即访问b网址,浏览器直接主动跳转到 a 地址)
302——代表暂时性转移 ,访问b 网址,服务器返回了a地址 ,浏览器直接跳转到a , 但下次访问 b 地址时 ,还是访问b地址,而不是 a 地址 ,如果服务器返回 302 则再跳转到 a 地址
304——客户端已经执行了GET,但文件(资源)未变化 ,浏览器会用自身缓存来用
403——请求不允许,没有权限
404——没有发现文件、查询或URl,请求地址错误
五、跨域 (knowledge point)
1、同源策略
- ajax 请求时 , 浏览器要求当前页面 和server 必须是 同源(安全),否则浏览器不给发送请求
- 同源:协议、域名、端口 ,三者必须是一致
- 前端 :http://a.com:8080/ server : https://b.com/api/xxx (没有写端口,但是默认80 =>绝对不同源!!! 协议、域名、端口都不一样
- 同源仅仅限制于浏览器 , 例如爬虫 就不是浏览器端,而是服务器端 所以他可以执行
加载图片css js 可无视同源策略
<img src=" 跨域的图片地址 " />
<link href=" 跨域的css地址 " />
<script src=" 跨域的js地址 " > </script>
<img/>
可用于统计打点 , 可使用第三方统计服务<link /> <script>
可使用CDN ,CDN 一般都是外域<script>
可实现JSONP
2、跨域
- 所有的跨域,都必须经过server端允许和配合
- 未经过 server 端允许就实现 跨域,说明浏览器有漏洞,危险信号
3、跨域解决方案
- 使用JSONP
- 使用CORS
六、JSONP (knowledge point)
jsonp和json是没有关系的,而是一种普通的ajax请求
html的src标签时可以进行跨域请求的,也就是说src可以接受一切服务器上的静态文件,也包括静态文件js
当A网站使用B服务器的数据,因为在不同的网段ajax无法进行跨域处理,但是如果对方将A网站需要的数据使用js进行封装,然后A网站可以通过src标签直接获取B服务器上的js文件,然后解析获取需要的数据
<script>
可绕过跨域限制- 服务器跨域任意动态拼接数据返回
- 所以,
<script>
就可以获得跨域的数据,只要服务端愿意返回
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>jsonp 演示</title>
</head>
<body>
<p>一段文字 1</p>
<script>
window.callback = function (data) {
console.log(data)
}
</script>
<script src="http://localhost:8002/jsonp.js?username=xxx&callback=abc"></script>
</body>
</html>
callback (
{ name: 'llllllaaaaa' }
)
结果
- 由于传入
username =xxx
,所以会把name: 'llllllaaaaa'
变成name: 'xxx'
- 由于传入
callback=abc
,所以
* 会把JavaScript 中的 callback(。。。。)变成 abc(。。。。)
* 会把html 中的 window.callback 变成 window.abc
jQuery 实现jsonp
$.ajax({
url:'http://localhost:8002/jsonp.js',
dataType:'jsonp',
jsonpCallback:'callback',
success:function(data){
console.log(data)
}
})
与这个相同<script src="http://localhost:8002/jsonp.js?username=xxx&callback=abc"></script>
,success 里面的相当于 window.callback
访问 https://editor.csdn.net/ ,服务端一定会返回一个HTML 文件吗?
不会,
服务端跨域任意动态拼接数据返回 ,只要符合 HTML格式要求
同理于 <script src ="https://imooc.com/getData.js">
不一定会返回一个js文件
作用
主要是为了解决跨域请求的问题
应用领域
一些网站的天气预报功能 股票动态信息显示