美文网首页React Native开发
【PIT】React-Native(15) PanRespond

【PIT】React-Native(15) PanRespond

作者: woow_wu7 | 来源:发表于2019-12-28 14:06 被阅读0次

    大纲
    react-native-scrollable-tab-view在安卓模拟器上报错
    react-native-echarts在安卓模拟器上不显示
    react-native-echarts中的echarts源码版本过低,造成andorid柱状图点击主要图消失?下载最新版本修改源文件!
    Animated动画组件
    hooks中如何实现一个动画( rn中 )
    Dimensions
    PixelRatio
    手势响应系统
    PanResponder
    Image,ImageBackground,Animated.Image
    AppState
    StyleSheet
    FlatList
    获取和清除缓存 react-native-http-cache
    获取组件(或元素)的宽高等信息 => (两种方法)
    react-native-debugger如何调试http请求,NetWork面板请求不显示问题
    复习:
    async函数
    cookie

    hooks中如何实现一个动画

    例子1:
    const List = () => {
      const left = new Animated.Value(-300)  // left的初始值,注意 Value是大写
      useEffect(() => {
        Animated.timing(left, { // 注意区分 timing,decay衰退,spring弹簧
          toValue: 110, // 终值
          duration: 1000
        }).start() // start开始动画
      })
      return (
        <Animated.View style={{left}}> // view的动画组件
          <Text>1111111</Text>
        </Animated.View>
      )
    }
    
    
    
    例子2:
    - 使用 useRef 实现
    - useRef 返回一个可变的ref对象,返回的对象将在组件的整个生命周期内存在
    - useRef.current 初始化为传递的参数
    const List = () => {
      const left = useRef(new Animated.Value(-300)).current
      useEffect(() => {
        Animated.timing(left, {
          toValue: 110,
          duration: 1000,
          useNativeDriver: false // 是否启用原生动画
        }).start()
      })
      return (
        <Animated.View style={{left}}>
          <Text>1111111111111</Text>
        </Animated.View>
      )
    }
    
    
    
    ------------------------------------
    例3:综合案例
    import React, {useRef} from 'react';
    import {Animated, PanResponder, Dimensions, StyleSheet} from 'react-native';
    const {height} = Dimensions.get('window'); // 获取手机的宽和高
    /**
     * @param {children} DOM reactElement
     * @param {initialTop} number 竖直方向初始值
     */
    /* eslint-disable no-unused-vars, react/jsx-props-no-spreading */
    function CardSheet({children, initialTop}) {
      const refCardAnimated = useRef(new Animated.Value(initialTop)).current;
      const panResponder = PanResponder.create({
        onStartShouldSetPanResponder: () => true, // 开始触摸时询问
        onStartShouldSetPanResponderCapture: () => true, // 父级获权,捕获
        onPanResponderRelease: (evt, gestureState) => {
          // 手势释放时触发
          // evt 原生的nativeEvent对象、gestureState手势对象
          // dy  -向上  +向下
          // dy 表示从触摸操作开始时的累计纵向路程
          Animated.timing(refCardAnimated, {
            toValue: gestureState.dy < 0 ? 0 : initialTop,
            duration: 50,
          }).start();
        },
      });
      return (
        <Animated.View
          pagingEnabled
          {...panResponder.panHandlers} // panHandlers对象
          style={[
            styles.container,
            {
              height,
              top: refCardAnimated,
            },
          ]}>
          {children}
        </Animated.View>
      );
    }
    const styles = StyleSheet.create({
      container: {
        width: '100%',
        position: 'absolute',
        overflow: 'scroll',
        zIndex: 99999,
        backgroundColor: 'white',
      },
    });
    export default CardSheet;
    

    https://reactnative.cn/docs/panresponder/#docsNav
    https://blog.codecentric.de/en/2019/07/react-native-animated-with-hooks/

    (6) PanResponder

    • 将多点触摸操作协调成一个手势
    • 它在原生事件之外提供了一个新的 gestureState 对象
    (1) gestureState对象
    onPanResponderMove: (event, gestureState) => {}
    - event: nativeEvent 对象
    - gestureState:
      - dx - 从触摸操作开始时的累计横向路程
      - dy - 从触摸操作开始时的累计纵向路程   !!!!!!!!!!!! 注意:dy 是有正负的,向上是负数,向下是正数 !!!!!!!!!!!!! 
      - vx - 当前的横向移动速度
      - vy - 当前的纵向移动速度
      - d:是 distance 路程的缩写
      - v: 是 velocity 速度的缩写
    
    (2) PanResponder.create()
    - 返回一个 panHandlers 对象
    

    (5) 手势响应系统

    (1) 响应者生命周期
    
    1. View要成为触摸事件响应者,有两个询问的方法:
    - onStartShouldSetResponder: (evt) => true     -- 在 ( 开始触摸 ) 的时候询问
    - onMoveShouldSetResponder: (evt) => true      -- 如果View不是响应者,在 ( 开始移动 ) 的时候再次询问
    
    
    
    2. 如果View返回true,并开始成为响应者,则下列事件可以被触发:
    - onResponderGrant: (evt) => {}      -- view要开始响应触摸事件了 ( grant: 是允许的意思 )
    - onResponderReject: (evt) => {}     -- 响应者现在“另有其人”而且暂时不会“放权”,请另作安排。
    
    - onResponderTerminationRequest: (evt) => true
      - 有其他组件请求接替响应者,当前的 View 是否“放权”?返回 true 的话则释放响应者权力。
      - Terminate: 是中止,结束的意思
    
    - onResponderTerminate: (evt) => {}  -- 响应者权力已经交出。
      - 这可能是由于其他 View 通过onResponderTerminationRequest请求的
      - 也可能是由操作系统强制夺权(比如 iOS 上的控制中心或是通知中心)
    
    
    
    3. evt 是一个合成事件
      - nativeEvent
        - changedTouches - 在上一次事件之后,所有发生变化的触摸事件的数组集合(即上一次事件后,所有移动过的触摸点)
        - locationX - 触摸点相对于当前元素的横坐标
        - locationY - 触摸点相对于当前元素的纵坐标
        - pageX - 触摸点相对于根元素的横坐标
        - pageY - 触摸点相对于根元素的纵坐标
    
    
    
    4. 优先级 ( 捕获ShouldSet事件处理 )
    - onStartShouldSetResponder 和 onMoveShouldSetResponder 是以冒泡的方式调用,所以最初点击的DOM最新调用
    - 如果父元素想优先于子元素响应的话,可以在捕获期拦截,在下面的事件中返回true,并在对应的函数中做处理
      - onStartShouldSetResponderCapture: (evt) => true,  
      - onMoveShouldSetResponderCapture: (evt) => true,
    

    (7) Animated动画组件

    (1) 两种类型的值
    - Animated.Value() 用于单个值
    - Animated.ValueXY() 用于矢量值
    
    (3) 三种动画类型
    - Animated.decay() 以指定的初始速度开始变化,然后变化速度越来越慢,直至停下 (decay是衰退的意思)
    - Animated.spring() 弹簧效果 (spring是弹簧,春天的意思)
    - Animated.timing() easeinout函数
    
    (4) 启动动画
    - start()用来启动动画
    
    (5) 启动原生驱动
    - 在动画配置中指定 useNativeDriver:true 使用原生动画驱动
    
    (6) 动画组件
    - 注意:组件必须经过特殊处理才能用于动画
    - 特殊处理指:把动画值绑定到属性上,并且在一帧帧执行动画时避免 react 重新渲染和重新调和的开销,此外还得在组件卸载时做一些清理工作
    - 可以直接使用动画的组件:
      - Animated.View
      - Animated.ScrollView  
      - Animated.Text
      - Animated.Image
    

    (8) Image,ImageBackground,Animated.Image

    • Animated.Image 可以直接使用的动画组件,注意使用该组件无需引入Image组件,是Animated的属性
    • ImageBackground 相当于web中的背景图片,可以在ImageBackground组件内添加任意多个子集

    (9) AsyncStorage

    • 不推荐使用AsyncStorage,使用 react-native-storage 代替
    • Deprecated:不推荐使用,反对
    • AsyncStorage是一个简单,异步,持久的key-value存储系统,是全局的,可用用来代替localstorage
    react-native-storage
    - backend:后端
    
    (1) storage.js
    import Storage from 'react-native-storage';
    import AsyncStorage from '@react-native-community/async-storage';
    const storage = new Storage({
      size: 1000,
      storageBackend: AsyncStorage, // for web: window.localStorage
      defaultExpires: 1000 * 3600 * 24,
      enableCache: true,
      sync: {
      },
    });
    // add to global environment
    // notice: should global import
    global.storage = storage;
    export default storage;
    
    
    
    (2) 全局引入
    - 在项目入口index.js中引入
    - import '..../storage.js';
    - 因为该模块只需要执行,而不用引入任何模块,所以直接import '路径/文件名' 即可 ( 即保证该文件执行过,才能挂载到global对象上 )
    

    https://github.com/sunnylqm/react-native-storage

    中文 https://github.com/sunnylqm/react-native-storage/blob/master/README.zh-CN.md

    (10) AppState

    • AppState 应用是在前台还是后台,在状态变化时通知您
    • AppState 通常在处理推送通知的时候,用来决定内容和对应的行为
    AppState 
    
    
    (1) AppState.currentState 
    - AppState.currentState 返回应用的当前状态,会一直保持更新
    - 在应用启动过程中,AppState.currentState可能为null,知道AppState从原生代码得到通知
    
    
    (2) 状态类型 status
    - active 前台
    - background 后台,分为几种情况
      - 在别的应用中
      - 停留在桌面
      - 对 Android 来说还可能处在另一个Activity中(即便是由你的应用拉起的)
    - [iOS] inactive - 此状态表示应用正在前后台的切换过程中,或是处在系统的多任务视图,又或是处在来电状态中。
    
    
    (3) 事件
    - change
    - focus (仅android, 用户和应用进行交互时触发)
    - blur (仅android,用户下拉通知抽屉时触发)
    
    
    (4) 方法
    - addEventListener()
    - removeEventListener()
    
    
    
    
    ---------------------------------
    (5) 实例
    ---------------------------------
    import React, { useState, useEffect } from 'react';
    import { AppState } from 'react-native';
    
    const statusObj = { // 支持的三种状态
      active: '应用正在前台运行',
      background: '应用正在后台运行',
      inactive: '应用切换中'
    }
    
    export const useAppStatus = () => {
      const [appStatus, setAppStatus] = useState(AppState.currentState) // AppState.currentState属性
      const listenStatus = (nextAppState) => {
        if (nextAppState in statusObj) {
          console.log(statusObj[nextAppState]);
          setAppStatus(statusObj[nextAppState])
        }
      }
      useEffect(() => {
        AppState.addEventListener('change', listenStatus) // AppState.addEventListener 事件
        return () => {
          AppState.removeEventListener('change', listenStatus) // AppState.removeEventListener 事件
        }
      }, [])
    
      return appStatus
    }
    

    (11) StyleSheet

    • marginVertical:上下两边的margin
    • marginHorizontal:左右两边的margin
    • transform: [{translateX: number}]
    • StyleSheet 提供了一种类似 CSS 样式表的抽象。
    StyleSheet
    
    
    (1) 方法
    - StyleSheet.create(obj)
    - StyleSheet.flatten(style) // 展平数组中的样式对象,或者样式对象,相同属性后面会覆盖前面的属性
    - StyleSheet.compose(style1, style2) // 组合
    
    (2) 属性 
    - StyleSheet.hairlineWidth // 最细的线条,一像素边框
      - 可以用来实现一像素边框
      - 这一常量始终是一个整数的像素值(线看起来会像头发丝一样细),并会尽量符合当前平台最细的线的标准。
      - 如果模拟器缩放过,可能会看不到这么细的线。
    - StyleSheet.absoluteFill
    

    transform https://reactnative.cn/docs/transforms/#docsNav

    (12) 获取和清除缓存

    • react-native-http-cache
    import * as CacheManager from 'react-native-http-cache';
    
    const formatCache = cache => {
      let cacheSize = Math.floor(cache / 1024);
      console.log(cacheSize, 'cacheSize');
      switch (true) {
        case cacheSize / 1024 > 1: {
          cacheSize = `${Math.floor(cacheSize / 1024)} MB`;
          break;
        }
        default: {
          cacheSize = `${cacheSize} KB`;
          break;
        }
      }
      console.log('cache-size =>', cacheSize);
      return cacheSize;
    };
    
    export const getCacheSize = async () => { // 获取缓存大小,注意getCacheSize()返回的是promise
      const cache = await CacheManager.getCacheSize();
      return formatCache(cache);
    };
    
    export const clearCache = async () => { // 清除缓存
      const res = await CacheManager.clearCache(); // clearCache()返回的也是promise
      console.log('清除缓存的返回值 =>', res);
      return res;
    };
    
    安卓报错修改路径:node_modules\react-native-http-cache\android\src\main\java\cn\reactnative\httpcache
    

    gitbub https://github.com/reactnativecn/react-native-http-cache
    安卓按readme配置后报错:https://www.jianshu.com/p/b99d3a46947f
    修改方法:
    //FileCache cache1 = ImagePipelineFactory.getInstance().getMainDiskStorageCache();
    FileCache cache1 = ImagePipelineFactory.getInstance().getMainFileCache();
    //FileCache cache2 = ImagePipelineFactory.getInstance().getSmallImageDiskStorageCache();
    FileCache cache2 = ImagePipelineFactory.getInstance().getSmallImageFileCache(
    安卓报错修改路径:node_modules\react-native-http-cache\android\src\main\java\cn\reactnative\httpcac

    (13) 获取组件(或元素)的宽高等信息

    (1)方法一
    - 在 View 组件中有 onLayout 事件
    - {nativeEvent: { layout: {x, y, width, height}}}
      - 通过 e.nativeEvent.layout 获取 x, y, width, height
      - 注意:这个事件会在布局计算完成后立即调用一次,不过收到此事件时新的布局可能还没有在屏幕上呈现,尤其是一个布局动画正在进行中的时候。
      - 如果遇到合成事件异步访问相关的警告,使用 event.persist()
    - 缺点:只在初次渲染的时候才会触发这个函数,而且此种方法获取的是组件相对于父组件的位置坐标。
    const onLayout = (e) => {
      e.persist();
      setCopyRightWidth(Math.floor(e.nativeEvent.layout.width))
    }
    
    
    
    (2)方法二
    - UIManager, findNodeHandle
    
    import { UIManager,  findNodeHandle } from 'react-native';
    <MyComponent  ref={(ref)=>this.myComponent=ref} />
    UIManager.measure(findNodeHandle(this.myComponent),(x,y,width,height,pageX,pageY)=>{
       //todo
    })
    

    http://erichuang.top/2018/05/21/ReactNative/React%20Native%E4%B9%8B%E8%8E%B7%E5%8F%96%E7%BB%84%E4%BB%B6%E4%BD%8D%E7%BD%AE%E4%B8%8E%E5%A4%A7%E5%B0%8F/

    https://www.jianshu.com/p/20c63afc04b8

    (14) react-native-debugger如何调试http请求

    react-native-debugger如何调试http请求 ---- NetWork面板请求不显示问题
    
    
    解决办法:
    - 路径:   node_modules\react-native\Libraries\Core\setUpXHR.js
    - 注释掉: // polyfillGlobal('XMLHttpRequest', () => require('../Network/XMLHttpRequest'));
    
    

    https://www.cnblogs.com/zhangtao1990/p/10016559.html

    (1) react-native-scrollable-tab-view

    react-native-scrollable-tab-view

    解决方案:

    (1) 解决方案:
    yarn add @react-native-community/viewpager
    react-native link @react-native-community/viewpager
    
    
    (2) 关于link
    添加包含原生代码的库需要几个步骤:
    1. npm install 某个带有原生依赖的库
    2. react-native link 某已安装的具体库名(注意:现在rn不需要link了,rn会自动link, 不需要手动link)
    经过以上两步,现在原生依赖就成功地链接到你的 iOS/Android 项目了。
    
    
    (3) 单词
    community:是社区的意思
    unpack: 打开,取出
    

    issues https://github.com/ptomasroos/react-native-scrollable-tab-view/issues/1050

    (2) react-native-echarts在安卓模拟器上不显示

    react-native-echarts在安卓模拟器上不显示
    
    
    1. 安装 react-native-webview
    - npm install react-native-webview -S
    
    2. 将node_modules\native-echarts\src\components\Echarts下的tpl.html复制到android\app\src\main\assets目录下,
       assets需要自己新建文件夹
    
    3. 修改react-native-echarts的源码
    - 在node_modules\native-echarts\src\components\Echarts下的index.js文件进行修改:
    - 将Webview组件的source配置项修改为:
    - source={Platform.OS === 'ios' ? require('./tpl.html') : {uri:'file:///android_asset/tpl.html'}}
    
    
            import { View, StyleSheet, Platform } from 'react-native';
            <WebView
              ref="chart"
              scrollEnabled = {false}
              injectedJavaScript = {renderChart(this.props)}
              style={{
                height: this.props.height || 400,
                backgroundColor: this.props.backgroundColor || 'transparent'
              }}
              scalesPageToFit={Platform.OS !== 'ios'}
              originWhitelist={['*']}
              source={Platform.OS === 'ios' ? require('./tpl.html') : {uri:'file:///android_asset/tpl.html'}}
              onMessage={event => this.props.onPress ? this.props.onPress(JSON.parse(event.nativeEvent.data)) : null}
            />
    

    https://www.cnblogs.com/lude1994/p/10647842.html
    de

    (3) react-native-echarts中的echarts源码版本过低,造成andorid柱状图点击主要图消失?下载最新版本修改源文件!

    修改前
    修改后
    1. 下载最新版本的echarts,建议定制化下载,并开启代码压的缩
    2. 找到RN中的native-echarts源码,修改native-echarts/src/components/Echarts/中的echarts.min.js和tpl.html
    3. tpl.html文件中的script标签中加载的就是echarts的源码,直接拷贝最新版的echarts.min.js替换掉
    
    4. 还要拷贝tpl.html文件到andorid/app/src/main/assets/tpl.html,替换掉这里的tpl.html
    // 如果没有assets文件夹自己新建一个
    

    (4) Dimensions

    • dimensions: 是尺寸,范围的意思
    const {height, width} = Dimensions.get('window');
    

    (5) PixelRatio

    PixelRatio
    - pixel:像素
    - pixelRatio:像素比
    - PixelRatio.get()
    - PixelRatio.getFontScale()
    - PixelRatio.getPixelSizeForLayoutSize()
    
    
    (1) PixelRatio.get() 
      - 返回设备的像素密度 // 1 2 3 3.5
    
    (2) PixelRatio.getFontScale() 
      - 返回字体缩放比例
      - 该比例用于计算绝对字体的大小
    
    (3)PixelRatio.getPixelSizeForLayoutSize() 
      - 将布局尺寸转换为像素尺寸,一定是返回一个整数数值
      - dp -> px
    






    复习 async函数

    • async函数返回一个promise对象,可以使用then方法添加回调函数
    • 一旦遇到await就会先返回,等异步操作执行完后,才会执行函数体后面的语句
    async 函数语法
    
    (1) 基本语法
    - async 函数返回一个promise对象
    - async 函数内部 return 语句的(返回值),会成为 then 方法回调函数的 (参数)
    - async 函数内部抛出错误,会导致返回的promise对象变成reject对象,可以被catch函数捕捉到
    
    
    (2) 状态变化
    - async 函数返回的promise对象,必须等到async函数内部所有await命令后面的promise对象执行完才会发成改变,除非遇到return或者抛出错误
      即:只有async函数内所有异步操作执行完成后,才会只执行then方法指定的回调函数、
    
    
    await命令
    
    - 如果 await 命令后是一个 promise 对象,返回该对象的结果,如果不是promise对象,就会直接返回后面对应的值
    - 如果 await 命令后是一个thenable对象(即定义了then方法的对象),await会将其等同于promsie对象
    - await命令 后面的promise对象如果变成reject状态,reject的参数会被catch捕获
    - 任何一个await命令后面的promise对象变为reject状态,整个async函数就会中断执行
    
    - 需求:如果希望前一个异步操作失败,也不要中断后面的异步操作
    - 两种方法
    - 1.
        const go = async () => {
          try {
            await Promise.reject('出错了')
          } catch(e) {
          }
          return await Promise.resolve('还是执行了') // 前面的promise报错了,但是该promise仍然执行了
        }
        go().then(res => console.log(res, 'res'))
    - 2.
    async function f() {
      await Promise.reject('出错了')
        .catch(e => console.log(e));
      return await Promise.resolve('hello world');
    }
    f()
    .then(v => console.log(v))
    // 出错了
    // hello world
    
    使用注意点
    
    - await命令后的promise对象可能是reject,所以最好使用try...catch保证能捕获错误,并且不会影响其他的await命令后的promise
    - await命令只能用在async函数中,用在普通函数中就会报错
    
    
    - async可以保留运行堆栈
    (1)
    const a = () => {
      b().then(() => c());
    };
    - 上面b执行时,a并没有中断执行而是继续执行,当b执行完时,可能a已经执行完
    - 所以b或者c函数中如果运行出错,则错误堆栈将可能不包括a
    ---------
    (2)
    const a = async () => {
      await b();
      c();
    };
    - 上面b执行时,a是中断执行的,a的上下文环境仍然保留
    - 所以b或者c出错,错误堆栈将包括a
    

    复习 cookie

    • cookie是服务器保存在浏览器的一小段文本信息
    • cookie的大小不能超过 4kb
    • 浏览器每次向服务器发送请求都会携带上cookie
    • cookie主要用来分辨两个请求是否来自同一个浏览器,和保存一些状态信息
    cookie
    
    
    1. cookie包含的信息
    - cookie的名字
    - cookie的值
    - 到期时间
    - 所属域名,默认是当前域名
    - 生效的路径,默认是当前网址
    - 总结下是 key value expires max-age domain path secure http-only
    如:
      - cookie中有 www.example.com
        - 如果根路径是  / ,==========> 表示该cookie对该域名的根路径和它的所有子路径有效
        - 如果根路径是  /forums,=====> 表示cookie只有在访问 www.example.com/forums及其子路径时才有效
      - forum:是论坛的意思
    
    2. 浏览器可以设置不接受cookie,也可以设置不向服务器发送cookie
    - window.navigator.cookieEnabled
    - document.cookie
    - window.navigator.cookieEnabled => 浏览器是否打开cookie功能,boolen值
    - document.cookie => 返回当前网页的cookie,可读写
    
    3. 浏览器对cookie的大小和数量限制
    - 数量:不超过30个,单个域名的cookie数量不应超过30个
    - 大小:不超过4kb
    
    4. 共享cookie的条件
    - 两个网址的域名和端口相同,就可以共享cookie
    - 不要求协议相同
    
    5. cookie由http协议生成,也主要供http协议消费
    
    6. 服务器如何在浏览器中------------------------------------------------------------------------> 服务器保存cookie
    - 需要http回应头中,放置 set-Cookie 字段
    - Set-Cookie
    - Set-Cookie:foo=bar // 在浏览器保存一个名为foo的cookie,值是bar
    - Set-Cookie: <cookie-name>=<cookie-value>; Domain=<domain-value>; Secure; HttpOnly 
      Set-Cookie除了cookie的值,还可以附加多个cookie的属性,没有顺序要求
    - 服务器如果希望在浏览器保存 Cookie,就要在 HTTP 回应的头信息里面,放置一个Set-Cookie字段。
    - 注意:HTTP回应可以包含多个 set-Cookie 字段
    
    7. 服务器如何修改已经存在的 cookie -------------------------------------------------------------> 服务器修改cookie
    - 必须满足四个条件:( key,domain,path,secure ) 都要匹配
    - 只要有一个属性不同,就会产生一个全新的 cookie,而不是替换原来的 cookie
    
    8. 浏览器发送cookie ---------------------------------------------------------------------------> 浏览器发送cookie
    - HTTP的头字段中设置 Cookie 字段
    - Cookie: foo=bar
    - Cookie字段可以包含多个cookie,用分号隔开
    
    9. 服务器收到浏览器发来的cookie,有两点是无法知道的
    - Cookie的各种属性
    - 那个域名设置的cookie,是一级域名还是二级域名等
    
    10. cookie的属性 ------------------------------------------------------------------------------> cookie的属性
    - Expires
    - Max-Age
    - Domain
    - Path
    - Secure
    - HttpOnly
    
    Expires
    - 指定一个具体的到期时间,时间到了后,浏览器就不会向服务器发送cookie
    - 值是 UTC 格式,可以使用Date.prototype.toUTCString()进行格式转换
    - 注意:如果Expires设置null,或者不设置,cookie只在当前会话有效,关闭浏览器后,cookie就会被删除
    - 注意:上面要 Expires 和 Max-Age 都未设置时,cookie在是会话cookie
    - 注意:浏览器是根据本地时间,决定cookie是否过期的
    
    Max-Age ----------------------------------------------------> 优先级 ( Max-Age > Expires ),同时设置,将采用 Max-Age
    ------------------------------------------------------------> 都未设置,则为会话cookie,只在当前会话有效
    - 指定从现在开始,cookie存在的秒数,单位是秒
    - 保存一年即 360 * 24 * 60 * 60
    
    Domain
    - 指定浏览器在发出HTTP请求时,哪些域名会附带这个cookie
    - 未指定,则默认是当前url的一级域名
    
    Path
    - 指定浏览器在发出HTTP请求时,哪些路径要携带这个cookie
    
    Secure
    - 指定浏览器只有在加密协议HTTPS下,才能将这个cookie发送到服务器
    - 如果当前协议是HTTP,则浏览器会忽略服务端发来的Secure属性
    
    HttpOnly
    - 指定该cookie无法通过js脚本拿到
    - 注意是该cookie,响应头中可以存在多个Set-Cookie字段,即多个cookie
    - ( Document.cookie,XMLHttpRequest对象,Request API 都拿不到cookie )
    
    11. Document.cookie
    - 读写当前网页的cookie
    - 读取 --------------------------------> 返回当前网页的 ( 所有cookie  )
    - 写入 --------------------------------> 一次只能写入 ( 一个cookie )
    - 浏览器向服务器发送cookie,-------------> 用一行 ( 全部发送 )
    - 服务器向浏览器设置cookie,-------------> Set-Cookie是一行设置 ( 一个cookie )
    - document.cookie读写行为的差异(一次可以读出全部 Cookie,但是只能写入一个 Cookie),与 HTTP 协议的 Cookie 通信格式有关
    - 写入cookie时要注意:
      - Expires是 UTC 时间,可以通过 Date.prototype.toUTCString() 进行日期格式化转换
      - Max-Age单位是 秒
      - Path是绝对路径
      - Domain必须是当前发送cookie的域名的一部分
    
    12. 删除cookie的唯一办法 
    ----------------------------------------------------------------> 删除cookie的唯一办法是设置 Expires 为一个过去的时间
    

    相关文章

      网友评论

        本文标题:【PIT】React-Native(15) PanRespond

        本文链接:https://www.haomeiwen.com/subject/rkaowctx.html