溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

js的cookie怎么使用

發(fā)布時間:2022-12-27 16:25:53 來源:億速云 閱讀:124 作者:iii 欄目:開發(fā)技術(shù)

本篇內(nèi)容主要講解“js的cookie怎么使用”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學(xué)習(xí)“js的cookie怎么使用”吧!

    源碼分析

    使用

    根據(jù)README,我們可以看到js-cookie的使用方式:

    // 設(shè)置
    Cookies.set('name', 'value');
    // 設(shè)置過期時間
    Cookies.set('name', 'value', { expires: 7 })
    // 獲取
    Cookies.get('name') // => 'value'
    // 獲取所有
    Cookies.get() // => { name: 'value' }
    // 獲取指定域名下
    Cookies.get('foo', { domain: 'sub.example.com' })
    // 刪除
    Cookies.remove('name')

    還有很多其他用和配置說明,大家可以自己去看看。

    源碼

    js-cookie的源碼并不多,src目錄下的api.mjs就是我們要分析的源碼,只有一百行左右。

    /* eslint-disable no-var */
    import assign from './assign.mjs'
    import defaultConverter from './converter.mjs'
    function init (converter, defaultAttributes) {
      function set (name, value, attributes) {
        if (typeof document === 'undefined') {
          return
        }
        attributes = assign({}, defaultAttributes, attributes)
        if (typeof attributes.expires === 'number') {
          attributes.expires = new Date(Date.now() + attributes.expires * 864e5)
        }
        if (attributes.expires) {
          attributes.expires = attributes.expires.toUTCString()
        }
        name = encodeURIComponent(name)
          .replace(/%(2[346B]|5E|60|7C)/g, decodeURIComponent)
          .replace(/[()]/g, escape)
        var stringifiedAttributes = ''
        for (var attributeName in attributes) {
          if (!attributes[attributeName]) {
            continue
          }
          stringifiedAttributes += '; ' + attributeName
          if (attributes[attributeName] === true) {
            continue
          }
          // Considers RFC 6265 section 5.2:
          // ...
          // 3.  If the remaining unparsed-attributes contains a %x3B (";")
          //     character:
          // Consume the characters of the unparsed-attributes up to,
          // not including, the first %x3B (";") character.
          // ...
          stringifiedAttributes += '=' + attributes[attributeName].split(';')[0]
        }
        return (document.cookie =
          name + '=' + converter.write(value, name) + stringifiedAttributes)
      }
      function get (name) {
        if (typeof document === 'undefined' || (arguments.length && !name)) {
          return
        }
        // To prevent the for loop in the first place assign an empty array
        // in case there are no cookies at all.
        var cookies = document.cookie ? document.cookie.split('; ') : []
        var jar = {}
        for (var i = 0; i < cookies.length; i++) {
          var parts = cookies[i].split('=')
          var value = parts.slice(1).join('=')
          try {
            var found = decodeURIComponent(parts[0])
            jar[found] = converter.read(value, found)
            if (name === found) {
              break
            }
          } catch (e) {}
        }
        return name ? jar[name] : jar
      }
      return Object.create(
        {
          set: set,
          get: get,
          remove: function (name, attributes) {
            set(
              name,
              '',
              assign({}, attributes, {
                expires: -1
              })
            )
          },
          withAttributes: function (attributes) {
            return init(this.converter, assign({}, this.attributes, attributes))
          },
          withConverter: function (converter) {
            return init(assign({}, this.converter, converter), this.attributes)
          }
        },
        {
          attributes: { value: Object.freeze(defaultAttributes) },
          converter: { value: Object.freeze(converter) }
        }
      )
    }
    export default init(defaultConverter, { path: '/' })
    /* eslint-enable no-var */

    分析

    js-cookie的源碼并不多,我們先來看看導(dǎo)出的是什么:

    export default init(defaultConverter, { path: '/' })

    這里是直接導(dǎo)出了init函數(shù)的返回值,我們來看看init函數(shù)的返回值:

    function init (converter, defaultAttributes) {
      // ...
      return Object.create(
        {
          set: set,
          get: get,
          remove: function (name, attributes) {
            set(
              name,
              '',
              assign({}, attributes, {
                expires: -1
              })
            )
          },
          withAttributes: function (attributes) {
            return init(this.converter, assign({}, this.attributes, attributes))
          },
          withConverter: function (converter) {
            return init(assign({}, this.converter, converter), this.attributes)
          }
        },
        {
          attributes: { value: Object.freeze(defaultAttributes) },
          converter: { value: Object.freeze(converter) }
        }
      )
    }

    這里是使用Object.create創(chuàng)建了一個對象,這個對象有set、get、remove、withAttributes、withConverter這幾個方法,這幾個方法都是在init函數(shù)內(nèi)部定義的,我們來看看這幾個方法的實現(xiàn):

    set

    function set(name, value, attributes) {
        if (typeof document === 'undefined') {
            return
        }
        attributes = assign({}, defaultAttributes, attributes)
        if (typeof attributes.expires === 'number') {
            attributes.expires = new Date(Date.now() + attributes.expires * 864e5)
        }
        if (attributes.expires) {
            attributes.expires = attributes.expires.toUTCString()
        }
        name = encodeURIComponent(name)
            .replace(/%(2[346B]|5E|60|7C)/g, decodeURIComponent)
            .replace(/[()]/g, escape)
        var stringifiedAttributes = ''
        for (var attributeName in attributes) {
            if (!attributes[attributeName]) {
                continue
            }
            stringifiedAttributes += '; ' + attributeName
            if (attributes[attributeName] === true) {
                continue
            }
            // Considers RFC 6265 section 5.2:
            // ...
            // 3.  If the remaining unparsed-attributes contains a %x3B (";")
            //     character:
            // Consume the characters of the unparsed-attributes up to,
            // not including, the first %x3B (";") character.
            // ...
            stringifiedAttributes += '=' + attributes[attributeName].split(';')[0]
        }
        return (document.cookie =
            name + '=' + converter.write(value, name) + stringifiedAttributes)
    }

    一行一行來看:

    if (typeof document === 'undefined') {
        return
    }

    首先判斷是否有document對象,如果沒有則直接返回,這說明js-cookie只能在瀏覽器環(huán)境下使用。

    attributes = assign({}, defaultAttributes, attributes)

    然后合并配置項,將defaultAttributes和傳入的attributes合并,這里的assign大家直接理解為Object.assign就好了。

    if (typeof attributes.expires === 'number') {
        attributes.expires = new Date(Date.now() + attributes.expires * 864e5)
    }
    if (attributes.expires) {
        attributes.expires = attributes.expires.toUTCString()
    }

    然后判斷expires是否是一個數(shù)字,如果是數(shù)字則將其轉(zhuǎn)換為一個Date對象;

    這里的864e5是一個常量,結(jié)尾的e5代表后面加5個0,也就是86400000表示一天的毫秒數(shù)。

    然后判斷expires是否存在,如果存在則將其轉(zhuǎn)換為UTC時間。

    name = encodeURIComponent(name)
        .replace(/%(2[346B]|5E|60|7C)/g, decodeURIComponent)
        .replace(/[()]/g, escape)

    這里對name進行了編碼,然后將name中的%、()進行了轉(zhuǎn)義。

    escape是一個內(nèi)置函數(shù),它的作用是將一個字符串轉(zhuǎn)換為UTF-8編碼的字符串,這里的escape是將(、)轉(zhuǎn)換為%28、%29。

    參考:escape()

    var stringifiedAttributes = ''
    for (var attributeName in attributes) {
        if (!attributes[attributeName]) {
            continue
        }
        stringifiedAttributes += '; ' + attributeName
        if (attributes[attributeName] === true) {
            continue
        }
        // Considers RFC 6265 section 5.2:
        // ...
        // 3.  If the remaining unparsed-attributes contains a %x3B (";")
        //     character:
        // Consume the characters of the unparsed-attributes up to,
        // not including, the first %x3B (";") character.
        // ...
        stringifiedAttributes += '=' + attributes[attributeName].split(';')[0]
    }

    這里是將attributes轉(zhuǎn)換為字符串,這里的stringifiedAttributes是一個字符串,最后的結(jié)果是這樣的:

    stringifiedAttributes = '; path=/; expires=Wed, 21 Oct 2015 07:28:00 GMT'

    最后將name、value、stringifiedAttributes拼接起來,然后賦值給document.cookie。

    get

    function get(name) {
        if (typeof document === 'undefined' || (arguments.length && !name)) {
            return
        }
        // To prevent the for loop in the first place assign an empty array
        // in case there are no cookies at all.
        var cookies = document.cookie ? document.cookie.split('; ') : []
        var jar = {}
        for (var i = 0; i < cookies.length; i++) {
            var parts = cookies[i].split('=')
            var value = parts.slice(1).join('=')
            try {
                var found = decodeURIComponent(parts[0])
                jar[found] = converter.read(value, found)
                if (name === found) {
                    break
                }
            } catch (e) {
            }
        }
        return name ? jar[name] : jar
    }

    get方法的實現(xiàn)比較簡單,主要是解析document.cookie,然后將其轉(zhuǎn)換為一個對象,來逐行解析:

    if (typeof document === 'undefined' || (arguments.length && !name)) {
        return
    }

    對比于set方法,這里多了一個(arguments.length && !name)的判斷,這里是防止傳入空字符串的name。

    var cookies = document.cookie ? document.cookie.split('; ') : []

    這里是將document.cookie分割為一個數(shù)組,每一項是一個cookie。

    var jar = {}
    for (var i = 0; i < cookies.length; i++) {
        var parts = cookies[i].split('=')
        var value = parts.slice(1).join('=')
    }

    這一步是只要cookienamevalue,其他的一些額外附加信息都不需要。

    try {
        var found = decodeURIComponent(parts[0])
        jar[found] = converter.read(value, found)
        if (name === found) {
            break
        }
    } catch (e) {
    }

    這里是將name進行了解碼,然后將namevalue存儲到jar對象中,如果傳入了name,則在找到對應(yīng)的name后就跳出循環(huán)。

    return name ? jar[name] : jar

    最后返回jar對象,如果傳入了name,則返回對應(yīng)的value,否則返回整個jar對象。

    這里的核心是converter.read,這個方法是用來解析value的,這里的converter是一個對象,它有兩個方法:

    /* eslint-disable no-var */
    export default {
      read: function (value) {
        if (value[0] === '"') {
          value = value.slice(1, -1)
        }
        return value.replace(/(%[\dA-F]{2})+/gi, decodeURIComponent)
      },
      write: function (value) {
        return encodeURIComponent(value).replace(
          /%(2[346BF]|3[AC-F]|40|5[BDE]|60|7[BCD])/g,
          decodeURIComponent
        )
      }
    }
    /* eslint-enable no-var */

    read方法是將value進行解碼,write方法是將value進行編碼。

    remove

    function remove(name, attributes) {
        set(
            name,
            '',
            assign({}, attributes, {
                expires: -1
            })
        )
    }

    remove方法就是使用set方法將value設(shè)置為空字符串,然后將expires設(shè)置為-1,這樣就相當(dāng)于刪除了cookie。

    withAttributes & withConverter

    Object.create({
        withAttributes: function (attributes) {
            return init(assign({}, defaultAttributes, attributes))
        },
        withConverter: function (converter) {
            return init(assign({}, defaultConverter, converter))
        }
    })

    這兩個方法就是用來設(shè)置defaultAttributesdefaultConverter的,這兩個對象是用來設(shè)置cookie的默認(rèn)屬性和默認(rèn)的converter。

    到此,相信大家對“js的cookie怎么使用”有了更深的了解,不妨來實際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進入相關(guān)頻道進行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!

    向AI問一下細節(jié)

    免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

    AI