mirror of
https://github.com/zhwei820/learn.lianglianglee.com.git
synced 2025-09-17 08:46:40 +08:00
683 lines
22 KiB
HTML
683 lines
22 KiB
HTML
<!DOCTYPE html>
|
||
|
||
<!-- saved from url=(0046)https://kaiiiz.github.io/hexo-theme-book-demo/ -->
|
||
|
||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||
|
||
<head>
|
||
|
||
<head>
|
||
|
||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||
|
||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=no">
|
||
|
||
<link rel="icon" href="/static/favicon.png">
|
||
|
||
<title>07 代理模式:帮我拿一下快递.md.html</title>
|
||
|
||
<!-- Spectre.css framework -->
|
||
|
||
<link rel="stylesheet" href="/static/index.css">
|
||
|
||
<!-- theme css & js -->
|
||
|
||
<meta name="generator" content="Hexo 4.2.0">
|
||
|
||
</head>
|
||
<body>
|
||
<div class="book-container">
|
||
|
||
<div class="book-sidebar">
|
||
|
||
<div class="book-brand">
|
||
|
||
<a href="/">
|
||
|
||
<img src="/static/favicon.png">
|
||
|
||
<span>技术文章摘抄</span>
|
||
|
||
</a>
|
||
|
||
</div>
|
||
|
||
<div class="book-menu uncollapsible">
|
||
|
||
<ul class="uncollapsible">
|
||
|
||
<li><a href="/" class="current-tab">首页</a></li>
|
||
|
||
</ul>
|
||
<ul class="uncollapsible">
|
||
|
||
<li><a href="../">上一级</a></li>
|
||
|
||
</ul>
|
||
<ul class="uncollapsible">
|
||
|
||
<li>
|
||
|
||
|
||
<a href="/专栏/白话设计模式 28 讲(完)/00 生活中的设计模式:启程之前,请不要错过我.md.html">00 生活中的设计模式:启程之前,请不要错过我.md.html</a>
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
<a href="/专栏/白话设计模式 28 讲(完)/01 监听模式:坑爹的热水器.md.html">01 监听模式:坑爹的热水器.md.html</a>
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
<a href="/专栏/白话设计模式 28 讲(完)/02 适配模式:身高不够鞋来凑.md.html">02 适配模式:身高不够鞋来凑.md.html</a>
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
<a href="/专栏/白话设计模式 28 讲(完)/03 状态模式:人与水的三态.md.html">03 状态模式:人与水的三态.md.html</a>
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
<a href="/专栏/白话设计模式 28 讲(完)/04 单例模式:你是我生命的唯一.md.html">04 单例模式:你是我生命的唯一.md.html</a>
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
<a href="/专栏/白话设计模式 28 讲(完)/05 职责模式:我的假条去哪了.md.html">05 职责模式:我的假条去哪了.md.html</a>
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
<a href="/专栏/白话设计模式 28 讲(完)/06 中介模式:找房子问中介.md.html">06 中介模式:找房子问中介.md.html</a>
|
||
</li>
|
||
|
||
<li>
|
||
<a class="current-tab" href="/专栏/白话设计模式 28 讲(完)/07 代理模式:帮我拿一下快递.md.html">07 代理模式:帮我拿一下快递.md.html</a>
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
<a href="/专栏/白话设计模式 28 讲(完)/08 装饰模式:你想怎么穿就怎么穿.md.html">08 装饰模式:你想怎么穿就怎么穿.md.html</a>
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
<a href="/专栏/白话设计模式 28 讲(完)/09 工厂模式:你要拿铁还是摩卡.md.html">09 工厂模式:你要拿铁还是摩卡.md.html</a>
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
<a href="/专栏/白话设计模式 28 讲(完)/10 迭代模式:下一个就是你了.md.html">10 迭代模式:下一个就是你了.md.html</a>
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
<a href="/专栏/白话设计模式 28 讲(完)/11 组合模式:自己组装电脑.md.html">11 组合模式:自己组装电脑.md.html</a>
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
<a href="/专栏/白话设计模式 28 讲(完)/12 构建模式:想要车还是庄园.md.html">12 构建模式:想要车还是庄园.md.html</a>
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
<a href="/专栏/白话设计模式 28 讲(完)/13 克隆模式:给你一个分身术.md.html">13 克隆模式:给你一个分身术.md.html</a>
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
<a href="/专栏/白话设计模式 28 讲(完)/14 策略模式:怎么来不重要,人到就行.md.html">14 策略模式:怎么来不重要,人到就行.md.html</a>
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
<a href="/专栏/白话设计模式 28 讲(完)/15 命令模式:大闸蟹,走起!.md.html">15 命令模式:大闸蟹,走起!.md.html</a>
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
<a href="/专栏/白话设计模式 28 讲(完)/16 备忘模式:好记性不如烂笔头.md.html">16 备忘模式:好记性不如烂笔头.md.html</a>
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
<a href="/专栏/白话设计模式 28 讲(完)/17 享元模式:颜料很贵必须充分利用.md.html">17 享元模式:颜料很贵必须充分利用.md.html</a>
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
<a href="/专栏/白话设计模式 28 讲(完)/18 外观模式:学妹别慌,学长帮你.md.html">18 外观模式:学妹别慌,学长帮你.md.html</a>
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
<a href="/专栏/白话设计模式 28 讲(完)/19 访问模式:一千个读者一千个哈姆雷特.md.html">19 访问模式:一千个读者一千个哈姆雷特.md.html</a>
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
<a href="/专栏/白话设计模式 28 讲(完)/20 生活中的设计模式:与经典设计模式的不解渊源.md.html">20 生活中的设计模式:与经典设计模式的不解渊源.md.html</a>
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
<a href="/专栏/白话设计模式 28 讲(完)/21 生活中的设计模式:那些未完待续的设计模式.md.html">21 生活中的设计模式:那些未完待续的设计模式.md.html</a>
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
<a href="/专栏/白话设计模式 28 讲(完)/22 深入解读过滤器模式:制作一杯鲜纯细腻的豆浆.md.html">22 深入解读过滤器模式:制作一杯鲜纯细腻的豆浆.md.html</a>
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
<a href="/专栏/白话设计模式 28 讲(完)/23 深入解读对象池技术:共享让生活更便捷.md.html">23 深入解读对象池技术:共享让生活更便捷.md.html</a>
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
<a href="/专栏/白话设计模式 28 讲(完)/24 深入解读回调机制:把你技能亮出来.md.html">24 深入解读回调机制:把你技能亮出来.md.html</a>
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
<a href="/专栏/白话设计模式 28 讲(完)/25 谈谈我对设计模式的理解.md.html">25 谈谈我对设计模式的理解.md.html</a>
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
<a href="/专栏/白话设计模式 28 讲(完)/26 谈谈我对设计原则的思考.md.html">26 谈谈我对设计原则的思考.md.html</a>
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
<a href="/专栏/白话设计模式 28 讲(完)/27 谈谈我对项目重构的看法.md.html">27 谈谈我对项目重构的看法.md.html</a>
|
||
</li>
|
||
|
||
</ul>
|
||
</div>
|
||
|
||
</div>
|
||
<div class="sidebar-toggle" onclick="sidebar_toggle()" onmouseover="add_inner()" onmouseleave="remove_inner()">
|
||
|
||
<div class="sidebar-toggle-inner"></div>
|
||
|
||
</div>
|
||
<script>
|
||
|
||
function add_inner() {
|
||
|
||
let inner = document.querySelector('.sidebar-toggle-inner')
|
||
|
||
inner.classList.add('show')
|
||
|
||
}
|
||
function remove_inner() {
|
||
|
||
let inner = document.querySelector('.sidebar-toggle-inner')
|
||
|
||
inner.classList.remove('show')
|
||
|
||
}
|
||
function sidebar_toggle() {
|
||
|
||
let sidebar_toggle = document.querySelector('.sidebar-toggle')
|
||
|
||
let sidebar = document.querySelector('.book-sidebar')
|
||
|
||
let content = document.querySelector('.off-canvas-content')
|
||
|
||
if (sidebar_toggle.classList.contains('extend')) { // show
|
||
|
||
sidebar_toggle.classList.remove('extend')
|
||
|
||
sidebar.classList.remove('hide')
|
||
|
||
content.classList.remove('extend')
|
||
|
||
} else { // hide
|
||
|
||
sidebar_toggle.classList.add('extend')
|
||
|
||
sidebar.classList.add('hide')
|
||
|
||
content.classList.add('extend')
|
||
|
||
}
|
||
|
||
}
|
||
|
||
|
||
function open_sidebar() {
|
||
|
||
let sidebar = document.querySelector('.book-sidebar')
|
||
|
||
let overlay = document.querySelector('.off-canvas-overlay')
|
||
|
||
sidebar.classList.add('show')
|
||
|
||
overlay.classList.add('show')
|
||
|
||
}
|
||
|
||
function hide_canvas() {
|
||
|
||
let sidebar = document.querySelector('.book-sidebar')
|
||
|
||
let overlay = document.querySelector('.off-canvas-overlay')
|
||
|
||
sidebar.classList.remove('show')
|
||
|
||
overlay.classList.remove('show')
|
||
|
||
}
|
||
</script>
|
||
<div class="off-canvas-content">
|
||
|
||
<div class="columns">
|
||
|
||
<div class="column col-12 col-lg-12">
|
||
|
||
<div class="book-navbar">
|
||
|
||
<!-- For Responsive Layout -->
|
||
|
||
<header class="navbar">
|
||
|
||
<section class="navbar-section">
|
||
|
||
<a onclick="open_sidebar()">
|
||
|
||
<i class="icon icon-menu"></i>
|
||
|
||
</a>
|
||
|
||
</section>
|
||
|
||
</header>
|
||
|
||
</div>
|
||
|
||
<div class="book-content" style="max-width: 960px; margin: 0 auto;
|
||
|
||
overflow-x: auto;
|
||
|
||
overflow-y: hidden;">
|
||
|
||
<div class="book-post">
|
||
|
||
<p id="tip" align="center"></p>
|
||
|
||
<div><h1>07 代理模式:帮我拿一下快递</h1>
|
||
|
||
<p>【故事剧情】</p>
|
||
|
||
<blockquote>
|
||
|
||
<p>八月中秋已过,冬天急速飞来……一场秋雨一场寒,十场秋雨穿上棉!在下了两场秋雨之后,Tony 已经冻的瑟瑟发抖了。周六,Tony 在京东上买了一双雪地鞋准备过冬了,但是忘了选择京东自营的货源,第二天穿新鞋的梦想又不能如期实现了。</p>
|
||
|
||
<p>周二,Tony 正在思考一个业务逻辑的实现方式,这时一通电话来了,“您好!圆通快递。您的东西到了,过来取一下快递!”。Tony 愣了一下,转念明白:是周六买的鞋子,本来以来第二天就能到的,所以填的是家里的地址。这下可好,人都不在家了,咋办呢?</p>
|
||
|
||
<p>Tony 快速思索了一下,他想起了住一起的邻居 Wendy。Wendy 是一个小提琴老师,属于自由职业者,平时在艺术培训机构或到学生家里上上课,她在家的时间比较多。于是赶紧拿起手机呼叫 Wendy 帮忙:“你好,在家吗?能帮忙拿一下快速吗?”……</p>
|
||
|
||
<p>万幸的是 Wendy 正好在家,在她的帮助下终于顺利拿到快递,减了不少麻烦。</p>
|
||
|
||
</blockquote>
|
||
|
||
<p><img src="assets/33b267f0-d89b-11e7-9b5d-a5f4543ad36e.jpg" alt="enter image description here" /></p>
|
||
|
||
<h3>用程序来模拟生活</h3>
|
||
|
||
<p>在生活中,我们经常要找人帮一些忙:帮忙收快递,帮忙照看宠物狗。在程序中,有一种类似的设计,叫代理模式。在开始之前,我们先来模拟一下上面的故事案例。</p>
|
||
|
||
<p>源码示例:</p>
|
||
|
||
<pre><code class="language-python">class ReceiveParcel:
|
||
|
||
"接收包裹"
|
||
def __init__(self, name):
|
||
|
||
self.__name = name
|
||
def getName(self):
|
||
|
||
return self.__name
|
||
def receive(self, parcelContent):
|
||
|
||
pass
|
||
class TonyReception(ReceiveParcel):
|
||
|
||
"Tony接收"
|
||
def __init__(self, name, phoneNum):
|
||
|
||
super().__init__(name)
|
||
|
||
self.__phoneNum = phoneNum
|
||
def getPhoneNum(self):
|
||
|
||
return self.__phoneNum
|
||
def receive(self, parcelContent):
|
||
|
||
print("货物主人:" + self.getName() + ", 手机号:" + self.getPhoneNum())
|
||
|
||
print("接收到一个包裹,包裹内容:" + parcelContent)
|
||
class WendyReception(ReceiveParcel):
|
||
|
||
"Wendy接收"
|
||
def __init__(self, name, receiver):
|
||
|
||
super().__init__(name)
|
||
|
||
self.__receiver = receiver
|
||
def receive(self, parcelContent):
|
||
|
||
print("我是" + self.__receiver.getName() + "的朋友, 我来帮他代收快递!")
|
||
|
||
if(self.__receiver is not None):
|
||
|
||
self.__receiver.receive(parcelContent)
|
||
|
||
print("代收人:" + self.getName())
|
||
</code></pre>
|
||
|
||
<p>测试代码:</p>
|
||
|
||
<pre><code class="language-python">def testProxy():
|
||
|
||
tony = TonyReception("Tony", "18512345678")
|
||
|
||
wendy = WendyReception("Wendy", tony)
|
||
|
||
wendy.receive("雪地靴")
|
||
</code></pre>
|
||
|
||
<p>输出结果:</p>
|
||
|
||
<pre><code>我是Tony的朋友, 我来帮他代收快递!
|
||
|
||
货物主人:Tony, 手机号:18512345678
|
||
|
||
接收到一个包裹,包裹内容:雪地靴
|
||
|
||
代收人:Wendy
|
||
</code></pre>
|
||
|
||
<h3>从剧情中思考代理模式</h3>
|
||
|
||
<p>从上面的示例中我们可以发现,包裹实际上是 Tony 的,但是 Wendy 代替 Tony 的身份帮忙接收了包裹,Wendy 需要使用 Tony 的身份并获得快递员的验证(Tony 手机号)才能成功接收包裹。像这样,一个对象完成某项动作或任务,是通过对另一个对象的引用来完成,这种模式叫代理模式。</p>
|
||
|
||
<p><strong>代理模式(Proxy Pattern)</strong>:给某一个对象提供一个代理,并由代理对象控制对原对象的引用。代理模式的英文叫做 Proxy 或 Surrogate,它是一种对象结构型模式。</p>
|
||
|
||
<p>在某些情况下,一个客户不想或者不能直接引用一个对象,此时可以通过一个称之为“代理”的第三者来实现间接引用。如上面的示例中,Tony 因为不在家,所以不能亲自接收包裹,但他可以叫 Wendy 来代他接收,这里 Wendy 就是代理,她代理了 Tony 的身份去接收快递。</p>
|
||
|
||
<h3>代理模式的模型抽象</h3>
|
||
|
||
<h4>代码框架</h4>
|
||
|
||
<p>代理模式有三个关键要素,它们分别是:</p>
|
||
|
||
<ol>
|
||
|
||
<li>主题(Subject):定义“操作/活动/任务”的接口类。</li>
|
||
|
||
<li>真实主题(RealSubject):真正完成“操作/活动/任务”的具体类。</li>
|
||
|
||
<li>代理主题(ProxySubject):代替真实主题完成“操作/活动/任务”的代理类。</li>
|
||
|
||
</ol>
|
||
|
||
<p>根据这三个要素,我们抽象出一个较为通用的代码框架。</p>
|
||
|
||
<pre><code class="language-python">class Subject:
|
||
|
||
"主题"
|
||
def request(self):
|
||
|
||
pass
|
||
class RealSubject(Subject):
|
||
|
||
"代理主题"
|
||
def request(self):
|
||
|
||
print("RealSubject todo something...")
|
||
class ProxySubject(Subject):
|
||
|
||
"代理主题"
|
||
def __init__(self, subject):
|
||
|
||
self.__realSubject = subject
|
||
def request(self):
|
||
|
||
self.preRequest()
|
||
|
||
if(self.__realSubject is not None):
|
||
|
||
self.__realSubject.request()
|
||
|
||
self.afterRequest()
|
||
def preRequest(self):
|
||
|
||
print("preRequest")
|
||
def afterRequest(self):
|
||
|
||
print("afterRequest")
|
||
def client():
|
||
|
||
"客户端调用类"
|
||
|
||
realObj = RealSubject()
|
||
|
||
proxyObj = ProxySubject(realObj)
|
||
|
||
proxyObj.request()
|
||
</code></pre>
|
||
|
||
<h4>类图</h4>
|
||
|
||
<p>上面的代码框架可用类图表示如下:</p>
|
||
|
||
<p><img src="assets/01a1acc0-d89c-11e7-9363-994f5e2a852c.jpg" alt="enter image description here" /></p>
|
||
|
||
<h4>基于框架的实现</h4>
|
||
|
||
<p>上面的示例代码中,ReceiveParcel 其实就是 Subject,TonyReception 其实就是 RealSubject,WendyReception 其实就是 ProxySubject,而 receive 其实就是 request。</p>
|
||
|
||
<p>我们可以按上面的框架对 WendyReception 进行稍微的改动,如下:</p>
|
||
|
||
<pre><code class="language-python">class WendyReception(ReceiveParcel):
|
||
|
||
"Wendy接收"
|
||
def __init__(self, name, receiver):
|
||
|
||
super().__init__(name)
|
||
|
||
self.__receiver = receiver
|
||
def receive(self, parcelContent):
|
||
|
||
self.preReceive()
|
||
|
||
if(self.__receiver is not None):
|
||
|
||
self.__receiver.receive(parcelContent)
|
||
|
||
self.afterReceive()
|
||
def preReceive(self):
|
||
|
||
print("我是" + self.__receiver.getName() + "的朋友, 我来帮他代收快递!")
|
||
def afterReceive(self):
|
||
|
||
print("代收人:" + self.getName())
|
||
</code></pre>
|
||
|
||
<p>测试代码不用变。自己跑一下,会发现输出结果和之前的是一样的。</p>
|
||
|
||
<h4>模型说明</h4>
|
||
|
||
<p>代理对象可以在客户端和目标对象之间起到中间调和的作用,并且可以通过代理对象隐藏不希望被客户端看到的内容和服务,或者添加客户需要的额外服务。</p>
|
||
|
||
<p>在实现生活中能找到非常的代理模式的模型:火车票/机票的代售点;银行支票在市场交易中用来代替现金,并提供对签发人账号上资金的控制;代表公司出席一些商务会议。</p>
|
||
|
||
<h5><strong>代理模式的优点</strong></h5>
|
||
|
||
<ol>
|
||
|
||
<li>代理模式能够协调调用者和被调用者,在一定程度上降低了系统的耦合度。</li>
|
||
|
||
<li>可以灵活地隐藏被代理对象的部分功能和服务,也增加额外的功能和服务。</li>
|
||
|
||
</ol>
|
||
|
||
<h5><strong>代理模式的缺点</strong></h5>
|
||
|
||
<ol>
|
||
|
||
<li>由于在客户端和真实主题之间增加了代理对象,因此有些类型的代理模式可能会造成请求的处理速度变慢。</li>
|
||
|
||
<li>实现代理模式需要额外的工作,有些代理模式的实现非常复杂。</li>
|
||
|
||
</ol>
|
||
|
||
<h3>应用场景</h3>
|
||
|
||
<p>(1)不想或者不能直接引用一个对象时</p>
|
||
|
||
<p>如在移动端加载网页信息时,因为下载真实大图比较耗费流量和性能,可以用一个小图代替进行渲染(用一个代理对象去下载小图),在真正点击图片时,才去下载大图,显示大图效果。还有 HTML 中的占位符,其实也是代理的思想。</p>
|
||
|
||
<p>(2)想对一个对象的功能进行加强时</p>
|
||
|
||
<p>如在字体(Font)渲染时,对粗体(BoldFont)进行渲染时,可使用字体 Font 对象进行代理,只要在对 Font 进行渲染后,进行一步加粗的操作即可。</p>
|
||
|
||
<p>(3)各种特殊用途的代理:远程代理、虚拟代理、Copy-on-Write 代理、保护(Protect or Access)代理、Cache 代理、防火墙(Firewall)代理、同步化(Synchronization)代理、智能引用(Smart Reference)代理。这部分具体的运用可查阅相关<a href="https://design-patterns.readthedocs.io/zh_CN/latest/structural_patterns/proxy.html">资料</a>。</p>
|
||
|
||
</div>
|
||
|
||
</div>
|
||
|
||
<div>
|
||
|
||
<div style="float: left">
|
||
|
||
<a href="/专栏/白话设计模式 28 讲(完)/06 中介模式:找房子问中介.md.html">上一页</a>
|
||
|
||
</div>
|
||
|
||
<div style="float: right">
|
||
|
||
<a href="/专栏/白话设计模式 28 讲(完)/08 装饰模式:你想怎么穿就怎么穿.md.html">下一页</a>
|
||
|
||
</div>
|
||
|
||
</div>
|
||
</div>
|
||
|
||
</div>
|
||
|
||
</div>
|
||
|
||
</div>
|
||
<a class="off-canvas-overlay" onclick="hide_canvas()"></a>
|
||
|
||
</div>
|
||
|
||
<script defer src="https://static.cloudflareinsights.com/beacon.min.js/v652eace1692a40cfa3763df669d7439c1639079717194" integrity="sha512-Gi7xpJR8tSkrpF7aordPZQlW2DLtzUlZcumS8dMQjwDHEnw9I7ZLyiOj/6tZStRBGtGgN6ceN6cMH8z7etPGlw==" data-cf-beacon='{"rayId":"70997b89abd83cfa","version":"2021.12.0","r":1,"token":"1f5d475227ce4f0089a7cff1ab17c0f5","si":100}' crossorigin="anonymous"></script>
|
||
|
||
</body>
|
||
|
||
<!-- Global site tag (gtag.js) - Google Analytics -->
|
||
|
||
<script async src="https://www.googletagmanager.com/gtag/js?id=G-NPSEEVD756"></script>
|
||
|
||
<script>
|
||
|
||
window.dataLayer = window.dataLayer || [];
|
||
function gtag() {
|
||
|
||
dataLayer.push(arguments);
|
||
|
||
}
|
||
gtag('js', new Date());
|
||
|
||
gtag('config', 'G-NPSEEVD756');
|
||
|
||
var path = window.location.pathname
|
||
|
||
var cookie = getCookie("lastPath");
|
||
|
||
console.log(path)
|
||
|
||
if (path.replace("/", "") === "") {
|
||
|
||
if (cookie.replace("/", "") !== "") {
|
||
|
||
console.log(cookie)
|
||
|
||
document.getElementById("tip").innerHTML = "<a href='" + cookie + "'>跳转到上次进度</a>"
|
||
|
||
}
|
||
|
||
} else {
|
||
|
||
setCookie("lastPath", path)
|
||
|
||
}
|
||
function setCookie(cname, cvalue) {
|
||
|
||
var d = new Date();
|
||
|
||
d.setTime(d.getTime() + (180 * 24 * 60 * 60 * 1000));
|
||
|
||
var expires = "expires=" + d.toGMTString();
|
||
|
||
document.cookie = cname + "=" + cvalue + "; " + expires + ";path = /";
|
||
|
||
}
|
||
function getCookie(cname) {
|
||
|
||
var name = cname + "=";
|
||
|
||
var ca = document.cookie.split(';');
|
||
|
||
for (var i = 0; i < ca.length; i++) {
|
||
|
||
var c = ca[i].trim();
|
||
|
||
if (c.indexOf(name) === 0) return c.substring(name.length, c.length);
|
||
|
||
}
|
||
|
||
return "";
|
||
|
||
}
|
||
</script>
|
||
</html>
|
||
|