跨域

跨域

什么是跨域?

答:在浏览器中,域名,端口,IP地址,协议,有任何一项不同,则跨域。

处理跨域的方式?

  • JSONP。原理:动态生成script标签
  • cors(后段开启)
  • 代理服务器:首先,服务器和服务器之间是不存在跨域问题的,因为同源策略只存于浏览器中,所以跨域也只是存在于浏览器中。所以在前端中,往后端发送网络请求时,可以先向本地模拟的服务器发送网络请求,然后本地模拟的服务器会进行请求的拦截,最后本地模拟的服务器在向后端有数据的服务器发送网络请求,并获取数据。所以数据就能由后端服务器返回到本地模拟的服务器,然后本地模拟的服务器在把数据返回给我们自己。然后本地模拟的服务器就是代理服务器

配置代理服务器的js

//手动在项目根目录创建vue.config.js
module.exports = {
  devServer: {
    host: 'localhost',
    port: 8080,
    proxy: {
      '/admin': {
        target: 'http://localhost:3000',// 要跨域的域名
        changeOrigin: true, // 是否开启跨域
      }, 
    }
  }
}

Token原理分析

跨域_第1张图片
如果通过了,说明用户已经登录了,那就可以返回客户端想要得到的数据。

注意:如果前端和后台之间如果不存在跨域问题,一般使用cookiesession来记录登录状态,反之,如果前端和后台存在跨域问题,一般是要使用token的方式来维持登录状态。

Git

第一步:初始化:git init

第二步:把文件添加到暂存区中git add .

第三步:提交git commit -m '自己起名字'

第四步:把仓库和云端仓库进行关联git remote add origin 一串码云或者GitHub网络地址

第五步:推送到主分支git push -u origin master

其他操作:

查看文件状态:git status

创建新的分支:git checkout -b 分支名

查看所有分支:git branch

&&和||

  • 表达式a && 表达式b : 计算表达式a(也可以是函数)的运算结果,如果为 True, 执行表达式b(或函数),并返回b的结果;如果为 False,返回a的结果;
  • 表达式a || 表达式b : 计算表达式a(也可以是函数)的运算结果,如果为 Fasle, 执行表达式b(或函数),并返回b的结果;如果为 True,返回a的结果;

形象记忆法:妈妈有两个儿子,小瘦(||)和小胖(&&),然后妈妈吩咐他们做两件事 小瘦因为瘦,所以妈妈比较喜欢,小胖因为胖,妈妈就不怎么喜欢

好了,开始做事了:
小瘦因为惹妈妈喜欢,所以第一件事做对了,那妈妈是极力表扬,并且呢第二件事也不用做了;如果第一件事做错了,那也没事,接着做第二件就好了,并返回第二件的结果
小胖因为不惹妈妈喜欢,所以第一件事做对了,妈妈也不会表扬,认为这是因该的,第二件事还得继续做,并且返回第二件事的结果;如果小胖第一件事做错了,那就不得了,妈妈会大骂一顿小胖,并且返回第一件事的结果,所以小胖第一件事必须不能错,错了就挨骂,错了就返回。而小瘦是,第一件事对了就表扬,也返回第一件事的结果,但是小瘦第一件事如果错了,啥事也没有,做第二件事就好了。

函数防抖debounce

作用:指触发事件后在规定时间内,函数只能执行一次,如果在规定时间内重复触发了该事件,则会重置计算函数执行时间。即一段时间内多次触发同一事件,只执行最后一次;或者只是在开始时执行一次,中间不执行。

一个需要频繁触发的函数,在规定的时间内,只让最后一次生效,前面的不生效

帮助理解:集气放大招

出处:给盒子绑定鼠标经过的事件,即鼠标经过一次,则盒子中的值加一,代码如下:

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) 
}

修改如下:

  1. 提公因式:元素可以改变,时间也可以改变,则可得两个新参,作为可以改变的参数
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)

把上述事件封装为一个函数(立即执行版):

需求:当鼠标进入盒子的时候,盒子中的数字加一次,此后在指定时间内再次触发该事件无效,即不加一,只有在指定时间过了以后,再次触发事件才执行加一操作。

与非立即执行函数不同的地方在于,当鼠标第一次进入盒子之后,盒子中的内容是:触发事件后,是经过一段时间后再执行函数;还是先执行一次函数,然后再执行防抖的思想。也就是在第一次执行上,它们的处理方式不同。

函数节流throttle

作用:规定在一个单位时间内,只能触发一次函数。如果这个单位时间内触发多次函数,只有一次生效。

补充: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发送并发请求

实现: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和POST

get请求:用params:{}

post请求:用data:{},这是放在请求体里面的

Axios的实例

创建对应的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的拦截器

拦截分为请求拦截响应拦截。而请求拦截又分为请求成功拦截请求失败拦截响应拦截也分为响应成功拦截响应失败拦截
跨域_第2张图片

注意:全局拦截用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);
})

你可能感兴趣的:(javascript)