create-react-app2.1,授权登陆,( ISO8061时间格式;UTC,GMT时间 ) ,动效,对象数组去重,字符集,base64转码,打包去掉.map文件

关键词:
create-react-app2.1.1重大改变,授权登陆,( ISO8061时间格式;UTC,GMT时间 ) ,动效,对象数组去重,字符集,base64转码,打包去掉.map文件,location, encodeURIComponent,word-wrap, word-break, white-space, text-overflow,onScroll, scrollIntoView,嵌套路由,子路由,滚动平滑css属性, background, proxy,redux-devtools-extension

(一) create-react-app 2.1

  • 默认支持sass和scss
    只需安装node-sass即可( yarn add node-sass )

  • 默认支持css-modules
    scss文件命名需要加上module
    比如: login.module.scss

  • 如何开启绝对路径
    1.在根目录下新建名为.env后缀的文件
    2.设置环境变量: NODE_PATH=src 即可把src目录作为根目录
    create-react-app的配置方式是它的webpack配置会自动选取'.env'文件并读取'NODE_PATH'环境变量,然后可用于绝对导入.自定义环境变量在开发和生产过程中都可以使用,因为变量是在构建时嵌入的,而不是运行时嵌入的,所以你的应用程序可以通过'process.env'访问它的环境
    https://www.imooc.com/article/37421

  • proxy的修改
    1.新版proxy代理只支持字符串模式了,如果是对象需要下载插件
    2.http-proxy-middleware
    (库地址) https://github.com/chimurai/http-proxy-middleware
    (教程) https://blog.csdn.net/weixin_36094484/article/details/82968545

  • 如何使用less
    1.安装less和less-loader
    cnpm install less less-loader --save
    2.修改webpack.config.dev.js和webpack.config.prod.js

在create-react-app中使用less


(1) 定义变量
// style files regexes
const cssRegex = /\.css$/;
const cssModuleRegex = /\.module\.css$/;
const sassRegex = /\.(scss|sass)$/;
const sassModuleRegex = /\.module\.(scss|sass)$/;
const lessRegex = /\.less$/;     ------------------------------- 添加这两行
const lessModuleRegex = /\.module\.(less)$/; ------------------- 添加这两行

(2)配置module的rules
         {
            test: lessRegex,
            exclude: lessModuleRegex,
            use: getStyleLoaders({ importLoaders: 2 }, 'less-loader'),
          },
          {
            test: lessModuleRegex,
            use: getStyleLoaders(
              {
                importLoaders: 2,
                modules: true,
                getLocalIdent: getCSSModuleLocalIdent,
              },
              'less-loader'
            ),
          },
  • 如何引入antd,并按需加载
    1.安装 cnpm install babel-plugin-import ( 用于按需加载组件代码和样式的 babel 插件 )
    2.在package.json中
    ------------或者webpack.config.dev,webpack.config.prod 中
    ------------或者自己新建.babelrc文件
如何引入antd,并按需加载


(1) 在package.json中添加:

 "plugins":[["import", {"libraryName": "antd", "style": "css"}]]

 "babel": {
   "presets": [
 "react-app"
     ],
    "plugins":[["import", {"libraryName": "antd", "style": "css"}]]     // 添加插件
 },

------------

(2) 在 webpack.config.dev(开发环境)和 webpack.config.prod 中
    {
            test: /\.(js|mjs|jsx|ts|tsx)$/,
            include: paths.appSrc,
            loader: require.resolve('babel-loader'),
            options: {
              customize: require.resolve(
                'babel-preset-react-app/webpack-overrides'
              ),
              plugins: [
                [
                  require.resolve('babel-plugin-named-asset-import'),
                  {
                    loaderMap: {
                      svg: {
                        ReactComponent: '@svgr/webpack?-prettier,-svgo![path]',
                      },
                    },
                  },
                ],
                // ["import", {"libraryName": "antd","libraryDirectory": "es","style": "css" }]  添加!!!
              ],
              // This is a feature of `babel-loader` for webpack (not Babel itself).
              // It enables caching results in ./node_modules/.cache/babel-loader/
              // directory for faster rebuilds.
              cacheDirectory: true,
              // Don't waste time on Gzipping the cache
              cacheCompression: false,
            },
          },
  1. 在package.json中修改 plugin
    "plugins": [
      [
        "import",
        {
          "libraryName": "antd",
          "libraryDirectory": "es",
          "style": true   ------------------------ 这里把css改为true
        }
      ]
    ]
  1. 在webpack.config.dev.js中修改getStyleLoaders()函数
const getStyleLoaders = (cssOptions, preProcessor) => {
  const loaders = [
    require.resolve('style-loader'),
    {
      loader: require.resolve('css-loader'),
      options: cssOptions,
    },
    {
      // Options for PostCSS as we reference these options twice
      // Adds vendor prefixing based on your specified browser support in
      // package.json
      loader: require.resolve('postcss-loader'),
      options: {
        // Necessary for external CSS imports to work
        // https://github.com/facebook/create-react-app/issues/2677
        ident: 'postcss',
        plugins: () => [
          require('postcss-flexbugs-fixes'),
          require('postcss-preset-env')({
            autoprefixer: {
              flexbox: 'no-2009',
            },
            stage: 3,
          }),
        ],
      },
    },
  ];
  if (preProcessor) {   ---------------------------------- 主要修改这里
    let loader = require.resolve(preProcessor);
    if (preProcessor === "less-loader") {  
      loader = {
        loader,
        options: {
          javascriptEnabled: true,   ------------------- 关键配置这里
        }
      }
      loaders.push(loader);
    }
  }
  return loaders;
};
  1. 新建them.less文件,在them.less中引入@import "~antd/dist/antd.less",再把them.less引入到项目的入口文件index.js中即可
them.less


@import "~antd/dist/antd.less";

@primary-color: #1890ff;                         // 全局主色
@link-color: #1890ff;                            // 链接色
@success-color: #52c41a;                         // 成功色
@warning-color: #faad14;                         // 警告色
@error-color: #f5222d;                           // 错误色
@font-size-base: 14px;                           // 主字号
@heading-color: rgba(0, 0, 0, .85);              // 标题色
@text-color: rgba(0, 0, 0, .65);                 // 主文本色
@text-color-secondary : rgba(0, 0, 0, .45);      // 次文本色
@disabled-color : rgba(0, 0, 0, .25);            // 失效色
@border-radius-base: 4px;                        // 组件/浮层圆角
@border-color-base: #d9d9d9;                     // 边框色
@box-shadow-base: 0 2px 8px rgba(0, 0, 0, .15);  // 浮层阴影     
  • 如何开启cssModules
如何开启cssModules


import React from 'react';
import { Input, Form, Button  } from 'antd';
import S from './login.module.scss';           --------------------- 引入

const FormItem = Form.Item;


export default class Login extends React.Component {
  render() {
    return (
      <div className={S.login} >   ---------------------------------- 写成对象的形式
        <Form>
          <FormItem>
            用户名:<Input></Input>
          </FormItem>
          <FormItem>
            密码:<Input></Input>
          </FormItem>
          <FormItem>
            <Button type="primary">登陆</Button>
          </FormItem>
        </Form>
      </div> 
    )
  }
}

redux-devtools-extension

import { createStore, combineReducers, applyMiddleware } from 'redux';
import { composeWithDevTools } from 'redux-devtools-extension';


const totalReducers = {

};

const store = createStore(
    combineReducers({
      ...totalReducers
    }),
    composeWithDevTools(
      applyMiddleware(),
    )
  );

export default store;

(二) 授权登陆

auth2.0.jpg
QQ截图20181020161556.png

(教程)http://www.cftea.com/c/2016/11/6703.asp

(猪八戒授权文档)http://open.zbj.com/wiki/getWikiCategoryAll?wikiid=8#header

react-facebook-login 和 react-google-login

     <GoogleLogin
            clientId="6099641770..................apps.googleusercontent.com"
            redirectUri="https://tools............app"
            buttonText="LOGIN WITH GOOGLE"
            autoLoad={false}
            onSuccess={this.responseGoogle}
            onFailure={this.responseGoogle}
            // accessType="offline"
            // uxMode="redirect"
            uxMode="popup"
            className="google-content"
            style={{border: 'none'}}
     />

    responseGoogle = async(response) => {
      if (response.error) {
      // message.error(response.error, 2)
      return;
      } else {
      try {
        let accessToken = response.accessToken;
        const params = {
          acToken: accessToken,
          userType: 'STORE',
        }
        const res = await carbonLoginApi(googleGet(params)); // 用google获取得token,换取本服务器token
        if ( res.status === 200 ) {
          const token = res.data.token;
          window.localStorage.setItem('token', token);
          // const meRes = await carbonLoginApi(profilesGet()); // 请求me接口,看是否需要修改密码
          // if ( meRes.status === 200 ) {
          //   if (res.data.isNeedModifyPassword) {
          //     console.log('请重新设置密码,')
          //   }
          // }
          this.props.history.push('/request')
        } 
      } catch (err) {
        message.error(err.message)
      }
    }
  }












(二) ISO8601标准时间格式 ---- UTC时间,GMT时间

--------- ISO 8601的标准格式是:YYYY-MM-DDTHH:mm:ss.sssZ
-----------------------------------------: year-month-dateThour:minute:second.millisecondZ
(1) utc时间
'2018-10-30T12:53:19.000Z'-------------这样的时间符合iso8601时间标准
T:表示UTC时间,UTC时间又叫世界协调时间
Z:表示时区-----如果没跟任何数字表示0时区( Z:时区,可以是:Z(UFC)、+HH:mm、-HH:mm )
T 也可以用空格表示,但是这两种表示有点不一样,T 其实表示 UTC,而空格会被认为是本地时区(前提是不通过 Z 指定时区)

> new Date('1970-01-01 00:00:00')   --------------------- 空格是本地时区
Thu Jan 01 1970 00:00:00 GMT+0800 (CST)

> new Date('1970-01-01T00:00:00')  ---------------------- T是utc时间
Thu Jan 01 1970 08:00:00 GMT+0800 (CST)

(2) gmt时间
'Thu Nov 01 2018 08:58:27 GMT+0800 '
GMT+0800 : 表示东八区时区------- new Date()得到的是GTM本地时间
(3) Date对象最重要的几个方法

Date.prototype.valueOf() ------- 使用时间戳时,都用valueOf转成时间戳提交到后端

valueOf方法返回实例对象距离时间零点(1970年1月1日00:00:00 UTC)对应的毫秒数,
该方法等同于getTime方法。

new Date( new Date().valueOf() )


new Date().valueOf -------------------------- 返回距离时间零点的毫秒数
返回:1541035593721


new Date( new Date().valueOf() )------------- 返回对应的GMT时间
返回:Thu Nov 01 2018 09:27:02 GMT+0800
var d = new Date();

d.valueOf() // 1362790014817
d.getTime() // 1362790014817
Date.prototype.toString() ------- toString方法返回一个完整的日期字符串。
var d = new Date(2013, 0, 1);

d.toString()
// "Tue Jan 01 2013 00:00:00 GMT+0800 (CST)"
d
// "Tue Jan 01 2013 00:00:00 GMT+0800 (CST)"


d 和 d.toString()返回结果是一样的,即 new Date()会自动调用toString()方法


( 因为toString是默认的调用方法,所以如果直接读取Date实例,就相当于调用这个方法。 )
Date.prototype.toISOString() ------- 返回对应的ISO8601格式的时间字符串
Date.prototype.toJSON() ------------- toJSON方法返回一个符合 JSON 格式的 ISO 日期字符串
toISOString() 和 toJSON()方法返回值是相等的

var d = new Date(2013, 0, 1);

d.toISOString()
// "2012-12-31T16:00:00.000Z"

d.toJSON()
// "2012-12-31T16:00:00.000Z"
moment.js
上周的开始时间UTC时间
const lastWeekStart = moment().subtract(1,"w").startOf('isoWeek').toDate().toJSON();
上周的结束时间UTC时间
const lastWeekEnd = moment().add(-1,"w").endOf('isoWeek').toDate().toJSON();




上个月的开始时间UTC时间
const lastMonthStart = moment().month(moment().month()-1).startOf('month').utc().format();
上个月的结束时间UTC时间
const lastMonthEnd = moment().month(moment().month()-1).endOf('month').utc().format();



----------
moment().subtract(Number, String); 减法 ---- 返回的是一个moment对象
moment().subtract(Number, String).toDate() ---- 返回get the native Date object,原时间对象
moment().subtract(Number, String).toISOString() ---- 返回ISO8601格式时间字符串
moment().subtract(1, 'days') === moment.add(-1, 'days')  减一天



moment().startOf('isoWeek'); ----- 返回ISO8601格式的moment对象
--- set to the first day of this week according to ISO 8601, 12:00 am







-----------------------------( isBetween )------------------------------------------------

moment().isBetween(moment-like, moment-like);
moment().isBetween(moment-like, moment-like, String);
// where moment-like is Moment|String|Number|Date|Array
// moment-like可以是一个Moment对象,字符串,数字....

moment('2010-10-20').isBetween('2010-01-01', '2012-01-01', 'year'); // false
moment('2010-10-20').isBetween('2009-12-31', '2012-01-01', 'year'); // true


( isBetween )
!!!!!!!!
    const todayStart = moment().startOf('day');    -- 返回的是今天的开始时间的moment对象
    const todayEnd = moment().endOf('day');

    if ( moment(item.lastReplyAt).isBetween(todayStart, todayEnd) ) {    -- isBetween
      createTime = moment(item.lastReplyAt).format('h:mm a');
    } else {
      createTime = moment(item.lastReplyAt).format('MM / DD')  // 格式化成月/日
    }
!!!!!!!!

目录:

  1. 数组(对象)去重
    --- (1) 数组的reduce方法,没重复push,重复不做任何操作
    --- (2) lodash库的 _.uniqWith(array, _.isEqual);
  2. word-break 属性
  3. word-wrap 属性
  4. white-space 属性
  5. text-overflow 属性
  6. Element.scrollIntoView
  7. 嵌套路由,子路由
    https://blog.csdn.net/hsany330/article/details/78114805
  8. componentWillReceiveProps
    https://www.cnblogs.com/gdsblog/p/7348375.html
    https://blog.csdn.net/huanghanqian/article/details/80721575
  9. scrollHeight = scrollTop + clientHeight
    https://www.jianshu.com/p/c14f85f109ee
    https://www.jb51.net/article/58688.htm
    onScroll事件 和 onWheel事件

8.1 scrollIntoView() ------------- 滚动当前元素到浏览器的可视区域
!! scrollIntoView()类似于 window.location.hash

  1. 滚动平滑css属性
    scroll-behavior: smooth; -- 平滑
el.scrollIntoView(); // 等同于el.scrollIntoView(true)
el.scrollIntoView(false);

方法可以接受一个布尔值作为参数。
如果为true,表示元素的顶部与当前区域的可见部分的顶部对齐(前提是当前区域可滚动);
如果为false,表示元素的底部与当前区域的可见部分的尾部对齐(前提是当前区域可滚动)。
如果没有提供该参数,默认为true。
  1. 伪元素和伪类
    https://www.cnblogs.com/m2maomao/p/7744227.html
  2. 正则对象
  3. background
    background-color
    background-image
    background-image:url()

background-size -----------!!
background-size: cover拉伸图片,有可能一部分会超出
bckground-size: contain缩放图片,有可能一部分会出现空白,无法填充满
http://www.w3school.com.cn/tiy/c.asp?f=css_background-size&p=8

background-position -----------!!
background-position: 第一个参数是水平位置,第二个参数垂直位置,如果规定了一个值,另一个值是50%
background-position: center center = background-position: center 是一样的
background-position: 50% 50% = 0%表示左上角,100%表示右下角
http://www.w3school.com.cn/cssref/pr_background-position.asp

background-attachment
background-attachment : ( scroll , fixed )元素内背景图片是否随元素滚动而移动
https://www.cnblogs.com/rain-null/p/7064136.html

background-repeat
background-origin
background-clip

  1. 动效(元素底部,从中间向两边组件变长的横线)
html:
<div className="animate">animate test</div>



css:
.animate {
  position: relative;  // 父元素相对定位,!!伪类就当前元素的子元素
  display: inline-block;
}
.animate::after {     // 伪类相当于当前元素的子元素,只是不在dom中
  content:'';         // 一定要有内容,否则伪元素不会被撑开
  position: absolute;
  left:0;             // 定位到父元素的底部
  bottom:0;
  height: 2px;
  background: blue;
  left: 50%;          // left和right都是50%,则伪类被挤压到宽度是0,看不见了
  right: 50%;
  transition: all 0.5s;
  display: inline-block;
}
.animate:hover::after {
  content: '';
  position: absolute;
  height: 2px;
  background: blue;
  left: 0;
  right: 0;                // hove的时候,还原div的长度,正好是中间向两边扩散
  display: inline-block;
}
  1. 全局作用域 , 函数作用域 ------------------- 链式作用域
    函数内部可以直接读取全局变量
    函数外部无法读取函数内部声明的变量
  2. lodash ----------------- isEqual
_.isEqual(value, other)  -------- 深度比较值是否相等

*值得类型可以是 数组,对象,等
*值得类型是对象时:不考虑继承属性(inherited: inherited是继承的意思),只比较自身属性

argument: 需要比较的两个值
return:   返回一个布尔值

  1. 函数
    函数声明时,如果使用表达式赋值给变量的形式,表达式后需要加分号,表示语句的结束。
  • 函数名视同变量名,存在函数名提升。(注意:是function关键字声明的函数存在函数名提升,而采用变量赋值声明的函数,不存在函数名提升,而仅仅是提升变量)
  • 不能在 ( if ) 或者 ( try catch) 语句中声明函数,因为函数名存在变量提升,注意是function关键字声明的函数
  • 函数的name属性, length属性, toString()方法
  • length属性返回形参的个数
  • 函数的toString返回函数的源码的字符串形式
  • 作用域:指变量存在的范围
  • 对于var命令来说,局部变量只能在函数内部声明,在其他区块中声明的变量,都是全局变量
  • 函数本身也是一个值,也有自己的作用域,和变量一样,函数的作用域是其声明时所在的作用域,与其运行时的作用域无关
  • 函数执行时的作用域,是函数定义时的作用域,而不是调用时的作用域
  • 很容易犯错的一点是,如果函数A调用函数B,却没考虑到函数B不会引用函数A的内部变量。
  • 函数内部声明的函数,作用域绑定在函数内部
  • 传递方式
    1. 传值传递:函数的参数是原始类型的值( 数字,字符串,布尔值 ),是传值传递,在函数内部修改参数值,不会影响函数外部---------------------------- 原始值的拷贝
    2. 传址传递:函数的参数是复合类型的值 (数组,对象,其他函数),是传址传递,在函数内部修改参数值,会影响函数外部---------------------------------- 原始值的地址
    3. 注意:函数内部修改的不是参数对象的某个属性,而是替换掉整个参数,这时不会影响原始值
  • IIFE立即执行函数
    function关键字出现在行首,一律解析成语句。所以function关键字出现在行首,认为是函数声明语句,不该以()圆括号结尾。所以function(){}()会报错
    (function(){}()); 或者(function(){})();----------------------注意分号是必须的
    以圆括号开头,引擎认为圆括号后面跟的是表达式,就不会报错
f();
var f = function (){};

---------------------------------- 等同于

var f;
f();
f = function () {};

(1) word-break 属性

word-break :规定自动换行的处理方法

  • word-break: break-all 允许在单词内换行
  • word-break: keep-all 只能在半角空格或连字符处换行。

( 文字超出自动换行 ) https://blog.csdn.net/ysynhtt/article/details/44301461
( 文字超出自动换行 ) http://www.cnblogs.com/loya1015/p/5992366.html
中文在div中会自动换行,英文和数字不会,英文没空格时会被认为是一个单词,则不会换行

(2) word-wrap 属性

word-wrap : 允许( 长单词 )或者( url地址 )换行到下一行

  • word-wrap: break-word 在长单词或 URL 地址内部进行换行。

对比

word-wrap: break-word ------------------- 整个单词一起被换行
word-break: break-all ---------------------- 单词内换行,单词会被分开

(3) white-space 属性

white-space 设置如何处理元素内的空白

  • white-space: nowrap 文本不换行,文本会在同一行上继续,直到遇到 br 标签为止
  • white-space: pre-wrap 保留空白符序列,但是正常地进行换行
  • white-space: pre-line 合并空白符序列,但是保留换行符
  • white-space: inherit 规定应该从父元素继承 white-space 属性的值
  • herit: 是继承的意思

(4) text-overflow 属性

text-overflow 文本溢出的css

  • text-overflow: ellipsis 显示省略符号来代表被修剪的文本。
  • text-overflow: string 使用给定的字符串来代表被修剪的文本。
  • text-overflow: clip 修剪文本。
  • clip是修剪得意思

https://blog.csdn.net/lpandeng/article/details/72885811
(显示x行后,超出显示...) https://www.cnblogs.com/like-xcm/p/5849630.html

超出设定大小的div后,文字显示 省略号


html
<div className="ellipsis">
  sfdsdfasfsdfasdf good welllllllllllllllll hao djfksjdkfs fsadfas sdf sdf s df sdf  
</div>


css
.ellipsis {
  width: 100px;
  height: 60px;
  background: yellow;
  word-break: break-all;   // 单词内换行,会分开单词
  word-wrap: break-word;  // 整个单词都会被换行,不会被分开
  text-overflow: ellipsis; // 文字溢出,显示省略号
  white-space: nowrap; // 不换行
  over-flow: hidden; // 这个一定不能忘了,否则不会显示省略号  
}

(1) 数组(对象数组去重)

采用数组的reduce方法
Array.reduce((累计变量,当前变量,当前位置,原数组) => {...}, 累计变量初始值);
Array.reduce((cumulate, current, index) => {...}, initial )
第一个参数是:函数,该函数又有4个参数
第二个参数是:累计变量的初始值
返回值: 返回值是最后一次的计算结果!!!



let _arr = [
 {id:'1', name:'wang'},
 {id:'2', name:'li'},
 {id:'3', name:'zhang'},
 {id:'4', name:'wu'},
 {id:'1', name:'wang'},
];
let _obj = {};
let result = _arr.reduce((cumulate, current) => {
  let _radom = _obj[current.id] ? '' : _ojb[current.id] = true && cumulate.push(current);
  return cumulate
}, [])   // 注意:这里给累计变量的初始值是一个空数组
         // result就是去重后的数组 


解析:
(1) 在react中,三元表达式的返回值,需要赋给一个变量,不然此处会报错

(2) 计算过程:
_ojb['1']不存在,就给_ojb['1']赋值为true (其他值也可以),并且往空数组中push对象{id:'1', name:'wang'},
...
...
_ojb['1']存在,则不做任何操作 ------------ 则重复项,并没有push到累计变量数组中
最后:返回累积变量数组



--------------------------------------------

lodash
 
_.uniqWith( 重复项数组, _.isEqual) 返回值就是去重的数组

字符集

javascript使用unicode字符集,javascript内部所有字符都使用unicode表示

base64转码

javascript原生提供两个base64相关方法

  • 什么是base64:
    base64是一种编码方法,可以将任意 转换成 0~9, A~Z, a~z, +, /64个字符组成的可打印字符
  • 作用:
    不出现特殊字符,和加密
  • 使用场景:
  1. 文本包含一些不可打印的符号, 则可以使用base64编码,转成可打印的字符
  2. 以文本方式转递二进制数据,可以使用base64编码
btoa():任意值转为 Base64 编码

atob():Base64 编码转为原来的值


这两个字符都不适合非 ASCII的字符
如: btoa('您好')会报错 




function b64Encode(str) {
  return btoa(encodeURIComponent(str));
}
function b64Decode(str) {
  return decodeURIComponent(atob(str));
}
b64Encode('你好') // "JUU0JUJEJUEwJUU1JUE1JUJE"
b64Decode('JUU0JUJEJUEwJUU1JUE1JUJE') // "你好"

var x = '中文';
decodeURIComponent(atob(btoa(encodeURIComponent(x))))    // 输出中文

react-create-app建立的项目把包去掉.map文件

  • map文件是帮助我们查看报错的位置的。
  • map文件由devtool属性控制,如果不想要map,注释掉就可以,大约webpack.config.prod.js第57行;

一个完整的url地址

http://localhost:8080/a/b/c?a=1&b=2#abc

window.location

( http://localhost:8080/a/b/c?a=1&b=2#abc )

protocol协议:-------- 'http:'    注意包括:
hostname域名:-------- 'localhost'
host域名+端口:------- 'localhost:8080'      包括主机名,":"和端口号
hash:--------------- '#abc' #号开始的url
search:------------- '?a=1&b=2'  ?开始的部分
pathname: ------------ '/a/b/c'  当前 URL 的路径部分,注意以 / 开头
origin: -------------- 'http://localhost:8080'   返回url中完整的协议和主机地址部分,包括端口
herf:---------------- 'http://localhost:8080/a/b/c?a=1&b=2#abc'    完整的url

// query:-------------- 'a=1&b=2'  window.location中没有query属性

proxy

create-react-app中设置proxy
https://segmentfault.com/q/1010000008508440/a-1020000008516740

"proxy": "http://image.baidu.com"

 getData = async() => {
   const res = await axios.
   get('/channel/listjson?pn=0&rn=30&tag1=明星&tag2=全部&ie=utf8')
    .then(res => console.log(res))
 }

 说明:

(1) 上面访问'/channel/listjson?pn=0&rn=30...'将被代理到下面的地址:
 ---------- "http://image.baidu.com/channel/listjson?pn=0&rn=30..."

(2) 所以在浏览器看来访问的是'/channel/listjson?pn=0&rn=30...' 所以不会有跨域问题




------------

interceptor

axios中的拦截器

You can intercept requests or responses before they are handled by then or catch.
你可以在请求或者响应的中,在then和catch方法前拦截请求



实例:

import axios from 'axios';
import { message } from 'antd';
const isDev = window.location.origin === '............'; 
const isLocalhost = window.location.origin === '.........................'; 
export const hostname = isDev || isLocalhost  ? '................' : '........................' ;


const _axios =  axios.create({
  baseURL: hostname,
  headers: {
    Accept: 'application/json',
    'Content-Type': 'application/json',
  },
});

_axios.interceptors.request.use(request => {     // 请求拦截
  const {token} = localStorage;
  if (token) {
    request.headers.token = token;
  }
  return request;
}, error => Promise.reject(error) )

_axios.interceptors.response.use(response => {   // 响应拦截
  return response; 
}, error => {
  if (error.response) {
    switch(error.response.status) {
      case 401:
        {
          message.config({
            maxCount: 1,
          });
          message.error('Login expired, please login again');
          window.location.href = '#/login';
          break;
        }
      case 500:
        {
          message.error('Network Error');
          break;
        }  
      default:
        break;  
    }
  }
  return  Promise.reject(error) 
})

export default _axios;
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,585评论 4 365
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,923评论 1 301
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 110,314评论 0 248
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,346评论 0 214
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,718评论 3 291
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,828评论 1 223
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,020评论 2 315
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,758评论 0 204
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,486评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,722评论 2 251
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,196评论 1 262
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,546评论 3 258
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,211评论 3 240
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,132评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,916评论 0 200
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,904评论 2 283
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,758评论 2 274

推荐阅读更多精彩内容

  • HTML 5 HTML5概述 因特网上的信息是以网页的形式展示给用户的,因此网页是网络信息传递的载体。网页文件是用...
    阿啊阿吖丁阅读 3,448评论 0 0
  • 第一部分 HTML&CSS整理答案 1. 什么是HTML5? 答:HTML5是最新的HTML标准。 注意:讲述HT...
    kismetajun阅读 27,114评论 1 45
  • 老实说,我其实是个完全没有自信的人。 我们平时见到的那些自信满满的人,在我看来,要么从小就在良好的环境下成长,受到...
    白羽君阅读 237评论 0 0
  • 灿烂年华里的伤(一) 对于季忆来说,现在的她最渴望不是一份美妙的爱情,而是一份真诚的友情。 ...
    邱蕤阅读 149评论 0 1