什么是跨域?
答:在浏览器中,域名,端口,IP地址,协议,有任何一项不同,则跨域。
处理跨域的方式?
script
标签同源策略
只存于浏览器中,所以跨域也只是存在于浏览器中。所以在前端中,往后端发送网络请求时,可以先向本地模拟的服务器
发送网络请求,然后本地模拟的服务器
会进行请求的拦截,最后本地模拟的服务器
在向后端有数据的服务器发送网络请求,并获取数据。所以数据就能由后端服务器返回到本地模拟的服务器
,然后本地模拟的服务器
在把数据返回给我们自己。然后本地模拟的服务器
就是代理服务器
。配置代理服务器的js
:
//手动在项目根目录创建vue.config.js
module.exports = {
devServer: {
host: 'localhost',
port: 8080,
proxy: {
'/admin': {
target: 'http://localhost:3000',// 要跨域的域名
changeOrigin: true, // 是否开启跨域
},
}
}
}
如果通过了,说明用户已经登录了,那就可以返回客户端想要得到的数据。
注意:如果前端和后台之间如果不存在跨域问题,一般使用cookie和session来记录登录状态,反之,如果前端和后台存在跨域问题,一般是要使用token的方式来维持登录状态。
第一步:初始化:git init
第二步:把文件添加到暂存区中git add .
第三步:提交git commit -m '自己起名字'
第四步:把仓库和云端仓库进行关联git remote add origin 一串码云或者GitHub网络地址
第五步:推送到主分支git push -u origin master
其他操作:
查看文件状态:git status
创建新的分支:git checkout -b 分支名
查看所有分支:git branch
形象记忆法:妈妈有两个儿子,小瘦(||)和小胖(&&),然后妈妈吩咐他们做两件事 小瘦因为瘦,所以妈妈比较喜欢,小胖因为胖,妈妈就不怎么喜欢
好了,开始做事了:
小瘦因为惹妈妈喜欢,所以第一件事做对了,那妈妈是极力表扬,并且呢第二件事也不用做了;如果第一件事做错了,那也没事,接着做第二件就好了,并返回第二件的结果
小胖因为不惹妈妈喜欢,所以第一件事做对了,妈妈也不会表扬,认为这是因该的,第二件事还得继续做,并且返回第二件事的结果;如果小胖第一件事做错了,那就不得了,妈妈会大骂一顿小胖,并且返回第一件事的结果,所以小胖第一件事必须不能错,错了就挨骂,错了就返回。而小瘦是,第一件事对了就表扬,也返回第一件事的结果,但是小瘦第一件事如果错了,啥事也没有,做第二件事就好了。
作用:指触发事件后在规定时间内,函数只能执行一次,如果在规定时间内重复触发了该事件,则会重置计算函数执行时间。即一段时间内多次触发同一事件,只执行最后一次;或者只是在开始时执行一次,中间不执行。
一个需要频繁触发的函数,在规定的时间内,只让最后一次生效,前面的不生效
帮助理解:集气放大招
出处:给盒子绑定鼠标经过的事件,即鼠标经过一次,则盒子中的值加一,代码如下:
var count = 0;
box.onmousemove = function(){
if(box.timer){
clearTimeout(box.timer);
}
box.timer = setTimeout(function(){
box.innerText = ++count;
},2000)
}
把上述事件封装为一个函数(非立即执行版):
函数封装为debounce,并且提取出公共的部分得:
function debounce(){
if(box.timer){
clearTimeout(box.timer);
}
box.timer = setTimeout(function(){
box.innerText = ++count;
},2000)
}
修改如下:
function debounce(ele , wait){
if(ele.timer){
clearTimeout(ele.timer);
}
ele.timer = setTimeout(function(){
box.innerText = ++count;
},wait)
}
但是这样改肯定不能满足想要达到的效果,继续分析:需要在给新参加一个 函数,即把一个函数当作形参,传入想要执行的内容,如在本例中,执行的就是:
box.innerText = ++count;
那就把它换成一个带有形参函数的函数,得:
function debounce (ele , wait,fn){
if(ele.timer){
clearTimeout(ele.timer);
}
ele.timer = setTimeout(function(){
fn();
},wait)
}
但此时会发现,元素ele
就变得没有什么意义,再修改代码为:
function debounce (fn, wait){
if(fn.timer){
clearTimeout(fn.timer);
}
fn.timer = setTimeout(function(){
fn();
},wait)
}
再分析发现,这个函数需要一个返回值,而且这个返回值必须是一个函数,以便调用的元素能直接绑定一个事件,可得最终的函数为:
function debounce (fn, wait){
return function (){
if(fn.timer){
clearTimeout(fn.timer);
}
fn.timer = setTimeout(function(){
fn();
},wait)
}
}
function debounce(fn, delay){
//记录上一次的延时器
var timer = null;
return function(){
//清除上一次的延时器
clearTimeout(timer);
//重新设置新的延时器
timer = setTimeout(function(){
fn.call(this)
},delay)
}
}
最后调用该函数的代码为:
box.onmousemove = debounce(function(){
box.innerText = ++count;
},3000)
把上述事件封装为一个函数(立即执行版):
需求:当鼠标进入盒子的时候,盒子中的数字加一次,此后在指定时间内再次触发该事件无效,即不加一,只有在指定时间过了以后,再次触发事件才执行加一操作。
与非立即执行函数不同的地方在于,当鼠标第一次进入盒子之后,盒子中的内容是:触发事件后,是经过一段时间后再执行函数;还是先执行一次函数,然后再执行防抖的思想。也就是在第一次执行上,它们的处理方式不同。
作用:规定在一个单位时间内,只能触发一次函数。如果这个单位时间内触发多次函数,只有一次生效。
补充:setTimeout和setInterval的区别
setTimeout只在指定时间后执行一次(一般情况下setTimeout用于延迟执行某方法或功能)
setInterval以指定时间为周期循环执行(setInterval则一般用于刷新表单,对于一些表单的假实时指定时间刷新同步)
function throttle(fn,delay){
//记录上一次函数的触发时间
var lastTime = 0;
return function{
var nowTime = Data.now();
if(nowTime - lastTime > delay){
fn();
lastTime = nowTime;
}
}
}
需求:做一个功能,但是需要发送两个请求,而且这两个请求必须同时到达后才能继续写下面的代码,何解?
解法:axios
发送并发请求
实现:axios.all([axios(), axios()]).then(res => console.log(res))
注意:axios.all([])
返回的结果是一个数组,使用 axios.spread 可将数组 [res1,res2]
展开为res1, res2
用法:
axios.all([axios(), axios()]).then(axios.spread(res1, res2) =>{
console.log(res1);
console.log(res2);
})
axios
提供了一个方法,即axios.default
用来配置一些全局配置,如
axios.default.baseURL = "xxxx"
axios.default.timeout = 5000
get
请求:用params:{}
post
请求:用data:{}
,这是放在请求体里面的
创建对应的axios
的实例:
const instance = axios.create({
baseURL: 'http://123.207.32.32:8000',
timeout: 5000
})
instance({
url: '/home/multidata'
}).then(res => {
console.log(res);
})
封装网络请求函数request
import axios from 'axios'
export function request(config){
const instance = axios.create({
baseURL: "xxxx",
timeout: 5000
});
return instance(config)
}
拦截分为请求拦截和响应拦截。而请求拦截又分为请求成功拦截,请求失败拦截;响应拦截也分为响应成功拦截,响应失败拦截。
注意:全局拦截用
axios.interceptors....
,而这里是实例
拦截。
使用场景:
①比如config
中的一些信息不符合服务的要求,如header
需要其他形式的
②比如每次发送网络请求时,都希望在界面上显示一个请求的图标
。
③某些网络请求,比如登录,是必须要携带一些特殊的信息,如token
,加入用户没有登录,那就把网络请求拦截掉,然后强制跳转到登录页面,让用户先登录。
//2 axios的拦截器
instance.interceptors.request.use(config =>{
//这里打印的是 发送请求的配置信息 且是成功发送出去时的配置信息
console.log(config);
//拦截之后,再对 config 配置信息做一层处理,最后一定一定要记得把config 返回出去
return config;
//即,有拦有还,再拦不难
},err =>{
console.log(err);
})
instance.interceptors.response.use(res =>{
//打印的是响应的结果
console.log(res);
//同样在这里也需要把拦截的结果返回出去,否则接收到的值就是一个 undefined
return res
},err =>{
console.log(err);
})