提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
同源策略(同源政策)
概述
浏览器为了安全性考虑 拒绝访问不同源的内容 这个称为同源策略
跨域(CORS)
跨域问题的产生 是由于同源策略的影响
1.请求协议不一致 (http 和 https)
2.ip地址不一致 (127.0.0.1 和 192.168.0.1)
3.端口不一致 (80 和 3306)
4.走的file协议 文件不一样也会跨域
跨域解决
1.后端解决 (设置请求头)
Access-Control-Allow-Origin: *
2.前端解决 (通过设置请求 jsonp)
jsonp
jsonp是一种访问形式,他只支持get请求(他需要服务器端配合)
主要利用的script标签不受跨域的影响 利用script标签给我们去返回一个js文件 执行
jsonp基础案例
function a(str){
console.log(str);
//ajax请求 自己请求自己
}
//给窗口添加一个方法
window["abc"] = a
//相当于这里会自动执行window的abc方法 也就是上面的a方法 将数据填入a方法的形参
<script src="https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?cb=abc&wd=hello"></script>
jsonp封装
function jsonp({
url, //链接地址
params,//参数 对象类型
callbackName,//回调函数名字
callback //回调函数
}){
//1.给window添加方法 方法名应该不能重复
//随机生成一个函数名
let fnName = "fn"+Date.now()+Math.ceil(Math.random()*10000)
//将对应回调函数添加给window 添加的函数名随机生成
window[fnName] = callback
//2.添加script
let script = document.createElement('script')
//3.将方法名拼接到url地址后面
url += `?${callbackName}=${fnName}`
//4.将参数再做拼接
let paramsStr = joinParams(params)
url += paramsStr
//5.将这个url地址给script标签 src属性
script.src = url
//6.将script加给body
document.body.appendChild(script)
//判断是否已经加载成功
script.onload = function(){
script.remove()
delete window[fnName]
}
}
function joinParams(params){
let str = ""
//取出对象里面的值
for(let key in params){
str+=`&${key}=${params[key]}`
}
return str
}
jsonp的promise封装
function jsonp({
url, //链接地址
params,//参数 对象类型
callbackName,//回调函数名字
}){
return new Promise((success,error)=>{
try{
//1.给window添加方法 方法名应该不能重复
//随机生成一个函数名
let fnName = "fn"+Date.now()+Math.ceil(Math.random()*10000)
//将对应回调函数添加给window 添加的函数名随机生成
window[fnName] = success //传递给.then方法的参数是success来传递
//2.添加script
let script = document.createElement('script')
//3.将方法名拼接到url地址后面
url += `?${callbackName}=${fnName}`
//4.将参数再做拼接
let paramsStr = joinParams(params)
url += paramsStr
//5.将这个url地址给script标签 src属性
script.src = url
//6.将script加给body
document.body.appendChild(script)
//判断是否已经加载成功
script.onload = function(){
script.remove()
delete window[fnName]
}
//如果加载出错的话 报错
script.onerror = function(){
error("加载问题")
}
}catch{//捕获错误
error("兄弟 脑子在想啥!!!")
}
})
}
function joinParams(params){
let str = ""
//取出对象里面的值
for(let key in params){
str+=`&${key}=${params[key]}`
}
return str
}
es7的async await
概述:
async(异步)表示当前修饰的函数里面有异步操作 await 等待异步操作完成才执行下面的内容
使用
1.async修饰的是函数 返回的值为一个promise对象
2.await是在async的中使用 如果不在async中使用会报错
3.await的右边 一般都是一个promise对象 等待这个promise对象执行到成功或者失败才会进行下一句(如果一致执行没有成功 后面的内容就不会再执行了)
4.async和await其实就是替代了繁琐的.then 以及 .catch
//es7新增了async同步 await 等待 俩个修饰来帮我们解决promise代码冗余的问题
//async 他是用来修饰函数的 函数执行他返回的也是一个promise对象
//里面东西他可以使用await来修饰 这个修饰也是一个promise对象
//async函数可能包含0个或者多个await表达式。await表达式会暂停整个async函数的执行进程并出让其控制权,
// 只有当其等待的基于promise的异步操作被兑现或被拒绝之后才会恢复进程。
(async function name(){ //这个函数调用返回值是一个promise对象
await a('张三',3000)
await a('李四',2000)
await console.log('哈哈哈哈');
console.log("123");
})()
// async function name(){}
// console.log(name());
//这个是一个函数这个函数返回一个promise对象
function a(str,time){
return new Promise((success,error)=>{
setTimeout(()=>{
console.log("点击了"+str); //后触发的
success()
},time)
})
}
//总结:
// async 是用于修饰函数 返回值是一个promise对象 async替代了promise
// await是async里面一个修饰符 当他修饰一个promise对象的时候 他会获取程序的控制权 直到完成或失败结束
//await替代了promise中的.then
// await关键字只在async函数内有效
try catch 异步捕获和处理
try 是进行错误的捕获 里面填写可能有错误的代码(数据请求)
cacth 块进行错误的处理(处理完是不报错的)
finally 块 不管是否错误都会执行的代码块
//捕获异常
try { //填写可能出错的代码
//这个里面可能会报错
console.log("hello");
throw new Error("长的太帅") //抛出一个错误异常
} catch (error) {
//捕获错误 只有错误才能进入 处理错误
console.log("中国人不骗中国人");
//进行处理
} finally{
//不管是否错误都会执行的代码块
console.log("小日子过得不错");
}
//finally 一般不用他有性能问题 try catch 也会影响性能
this
this表示的是这个 this一般在函数内 或者是对象内容使用
function里面的this指向 指向其调用者
function sayHi(){
console.log(this)
}
sayHi() //打印window
var obj = {
name : '王五'//键值对象
}
console.log(obj.name)//王五
function sayHello(){
this.sayHi = sayHi() //指向对象实例
this.fn=()=>{
console.log(this)
this.obj = obj
}
}
sayHello() //方法调用 打印window
sayHello().fn() //报错fn of undefined
sayHello.fn() // undefined
new sayHello().fn() //指向对象实例
箭头函数this 会指向上一层对象里面this (箭头函数没有this)
()=>{
this.a = 10 //this指向window
()=>{
console.log(this) //指向window
}
}
深拷贝和浅拷贝
let a = {}
let b = a //使用的是浅拷贝 相当于把对象地址给b
a.name = 10 //a的地址和b的地址指向同一个内容 a里面添加一个name b也添加
console.log(b.name) //10
深拷贝 拷贝所有的内容(跟原本内容没有关系)
1.递归遍历 没有对象结束
2.使用JSON.parse (常用)
let a = [1,2,3,{name:1,age:2,list:[1,2]}]
let str = JSON.stringify(a)
let aCopy = JSON.parse(str)
console.log(a == aCopy); //false
浅拷贝 只拷贝第一层内容 (对于里面的数组或者是对象拿到是引用地址)
示例
//深拷贝
let a = [1,2,3,{name:1,age:2,list:[1,2]}]
let str = JSON.stringify(a)
let aCopy = JSON.parse(str)
console.log(a == aCopy); //false
console.log(aCopy[3] == a[3]); //false
//浅拷贝
let arr = []
for(let key in a){
arr[key] = a[key]
}
console.log(arr[3] === a[3]); //true 拷贝的是对象的地址