Ajax
async javascript and XML
实现前端与服务器的连接 发送或接受信息
var xhr = new XMLHttpRequest() //创建ajax对象
xhr.open('GET/POST','xxx',true) //配置本次请求信息 xhr.open('请求方式','请求地址','是否异步')
xhr.onload = function (){ //注册请求完成事件
console.log('请求完成') //请求发送出去,服务器接受到了请求,并且服务器返回的信息已接收
var params=JSON.parse(xhr.responseText) //拿到后端返回的参数
}
xhr.setRequestHeader('content-type','xxx') //请求方式为POST提交参数的特殊说明
xhr.send(xxx) //把请求发送出去(如果请求方式为GET参数xxx为空)
请求方式:GET为获得数据 POST为提交数据 按照接口文档书写
请求地址:按照接口文档书写
是否异步:默认是true表示异步请求,选填为false 表示同步请求
请求方式
GET
偏向获取的语义化 参数是查询字符串 大小有限制2KB左右 参数位置在地址后面
xhr.open(‘GET’,‘xxx’,true)
xxx后接?key=value&key2=value2
POST
偏向提交的语义化 参数格式多样 但是需要特别说明 理论上没有限制
xhr.send()
里面的参数为key=value&key2=value2
POST请求不需要在地址后面拼接参数
当发送POST请求,并且需要携带参数时,需要进行特殊说明
xhr.setRequestHeader(‘content-type’,‘传递的参数格式(按照接口文档书写)’)
XML
extension markup language
文件后缀以.xml结束,一般用于存储数据,数据传输
xml必须要有一个文档声明
xml文件中的标签都是自定义的,不能使用xml关键字作为标签名且一定要有一个唯一的根标签
标签可以有属性-属性的值一定是字符串
<?xml version="1.0" encoding="utf-8"?> //文档声明
<shop> //此时shop为根标签
<goods>toys</goods>
<goods>food</goods>
</shop>
如果ajax接收的文件类型为xml
xhr.onload=function(){
let res=xhr.responseXML //接收文件类型为XML,接收的是一个文档,类似DOM中的document
let eles=res.getElementByTagname('goods') //操作元素
for(let i=0;i<eles.length;i++){
console.log(goods[i].innerHTML)
}
}
Ajax封装
对象键值对拼接为query
const obj = {
name: 'Tony',
age: 18,
gender: '男'
}
//字符串拼接1
let str = ''
for (let key in obj) {
str += key + '=' + obj[key] + '&'
}
str = str.slice(0, str.length - 1)
//字符串拼接2
let str = ''
for (let key in obj) {
str += '&' + key + '=' + obj[key]
}
str = str.slice(1)
//字符串拼接3
let str = ''
let f = ''
for (let key in obj) {
str += f + key + '=' + obj[key]
f = '&'
}
//数组拼接4
const arr = []
for (let key in obj) {
arr.push(key + '=' + obj[key])
}
const str = arr.join('&')
封装ajax框架错误处理
//框架内部抛出错误
if(!url){
throw new Error(`error`)
}
//报错时不执行后续业务逻辑 console.log("ok")不执行
//当这段代码有被抛出错误 用try
try{
//可能抛错的代码
}
//捕获抛出错误 不影响后续业务逻辑 console.log("ok")执行
catch{
console.log("err:");
}
console.log("ok");
eval()函数
ajax请求获得的数据不能作为js代码立可执行
eval()函数可以将字符串作为js代码立即执行
同时可以将数组字符串转换成对象
禁止使用eval!!!
eval() 是一个危险的函数, 它使用与调用者相同的权限执行代码。
如果你用 eval() 运行的字符串代码被恶意方(不怀好意的人)修改,您最终可能会在您的网页/扩展程序的权限下,在用户计算机上运行恶意代码。
更重要的是,第三方代码可以看到某一个 eval() 被调用时的作用域,这也有可能导致一些不同方式的攻击。相似的 Function 就不容易被攻击。
以下四种调用都可以将字符串作为js代码立即执行 ,但均不建议使用
使用eval("要执行的字符串")
使用new Function("要执行的字符串")
setTimeOut("要执行的字符串",500)
setInterval("要执行的字符串",500)
fetch()函数
浏览器自带fetch()函数用于发送请求,相当于ajax
fetch()函数为一个Promise对象
fetch('http://localhost:8000/api/data')
.then(response => response.json())
.then(result => console.log(result))
response.json()
接收一个 Response 流,并将其读取完成,它返回一个 Promise,Promise 的解析 resolve 结果是将文本体解析为 JSON。
跨域
1.JSONP
jsonp跨域原理:利用某些标签在发送请求的时候,不受同源策略的限制
img标签引入别的网站的图片链接-会把请求回来的数据当成图片解析
link标签引入别的网站的样式文件-会把请求回来的数据当成css解析
iframe标签引入别的网站地址-会把请求回来的数据当成html文档解析
script标签引入别的网站的js文件-会把请求回来的数据当成js代码解析
script标签访问任何url都是不受同源策略限制的
不管拿到的内容具体是什么,都视为JS代码立即执行
利用这两个特性,当需要跨域时,造一个script标签,为其src标签配置请求地址,即可拿到数据
利用JSONP需要服务端配合,将数据以函数调用的方式返回,json数据外层的函数为填充物padding
所以jsonp意为jsonpadding
根据请求动态创建标签,请求几次创建几次,所以得到数据后要销毁标签
2.Proxy服务器正向代理
1.nginx
服务器之间互访不受同源策略限制
想访问谁,让同源的Nginx服务器访问
在Nginx.conf中配置代理
无需服务器的配合
2.http-proxy-middleware中间件
通过在node中安装的http-proxy-middleware提供正向代理,跟服务器代理同理
注:
服务于前端的为正向代理 跨域
服务于后端的为反向代理 负载均衡
3.CORS
服务端设置响应头
'Access-Control-Allow-Origin':'白名单(*)'