网站优化:浏览器缓存控制简介及配置策略

每次访问网页,通常浏览器会从服务器下载所 需的资源,例如 HTML 文档、图片、CSS、JavaScript,甚至包括字体文件等。这里面的许多文件(例如图片)都是很少变动的,如果每次都要从服务器重新下载,会不必要 地增加网页载入时间,同时也会对服务器造成一定压力。通过合理配置缓存策略,可令浏览器以某种方式把这些静态的文件缓存起来,下次请求同一资源时,直接使 用本地存储的副本,而不是从服务器重新下载。 启用缓存至少有两点显而易见的好处: 减少页面加载时间 减少服务器负载 浏览器是否使用缓存、缓存多久,是由服务器控制的。准确来说,当浏览器请求一个网页(或者其他资源)时,服务器发回的响应的「响应头」部分的某些字段指明了有关缓存的关键信息。 Cache-Control Cache-ControlHTTP 响应头是 HTTP 1.1 协议新增的指令,每个资源都可以通过设定 Cache-Control 来建立缓存策略。通常,可为它指定一个max-age,表示缓存的最长时间,单位为秒。例如,若设定Cache-Control:… Read More

关于大型网站技术演进的思考(一)–存储的瓶颈(1)

前不久公 司请来了位互联网界的技术大牛跟我们做了一次大型网站架构的培训,两天12个小时信息量非常大,知识的广度和难度也非常大,培训完后我很难完整理出全部听 到的知识,今天我换了个思路是回味这次培训,这个思路就是通过本人目前的经验和技术水平来思考下大型网站技术演进的过程。 首先我们 要思考一个问题,什么样的网站才是大型网站,从网站的技术指标角度考虑这个问题人们很容易犯一个毛病就是认为网站的访问量是衡量的指标,懂点行的人也许会 认为是网站在单位时间里的并发量的大小来作为指标,如果按这些标准那么像hao123这样的网站就是大型网站了,如下图所示: 其实这种网站访问量非常大,并发数也非常高,但是它却能用最为简单的web技术来实现:我们只要保持网站的充分的静态化,多部署几台服务器,那么就算地球上所有人都用它,网站也能正常运行。 我觉得大型网站是技术和业务的结合,一个满足某些用户需求的网站只要技术和业务二者有一方难度很大,必然会让企业投入更多的、更优秀的人力成本实现它,那么这样的网站就是所谓的大型网站了。 一个初建 的网站往往用户群都是很小的,最简单的网站架构就能解决实际的用户需求,当然为了保证网站的稳定性和安全性,我们会把网站的应用部署到至少两台机器上,后 台的存储使用数据库,如果经济实力允许,数据库使用单台服务器部署,由于数据是网站的生命线,因此我们常常会把部署数据库的服务器使用的好点,这个网站结 构如下所示: 这个结构 非常简单,其实大部分初建网站开发里往往业务逻辑没有企业级系统那么复杂,所以只要有个好的idea,建设一个新网站的成本是非常低的,所使用的技术手段 也是非常的基本和简单,不过该图我们要准备三台服务器,而且还要租个机房放置我们的服务器,这些成本对于草根和屌丝还是非常高的,幸运的是当下很多大公司 和机构提供了云平台,我们可以花费很少的钱将自己的应用部署到云平台上,这种做法我们甚至不用去考虑把应用、数据库分开部署的问题,更加进一步的降低了网 站开发和运维的成本,但是这种做法也有一个问题,就是网站的小命被这个云平台捏住了,如果云平台挂了,俺们的网站服务也就跟着挂了。 这里我先讲讲自己独立使用服务器部署网站的问题,如果我们要把网站服务应用使用多台服务器部署,这么做的目的一般有两个:… Read More

关于大型网站技术演进的思考(二)–存储的瓶颈(2)

上篇里我讲到某些网站在高并发下会报出503错误,503错误的含义是指网站服务端暂 时无法提供服务的含义,503还表达了网站服务端现在有问题但是以后可能会提供正常的服务,对http协议熟悉的人都知道,5开头的响应码表达了服务端出 现了问题,在我们开发测试时候最为常见的是500错误,500代表的含义是服务端程序出现了错误导致网站无法正常提供服务,500通常是服务端异常和错误 所致,如果生产系统里发现了500错误,那么只能说明网站存在逻辑性的错误,这往往是系统上线前的测试做的不到位所致。回到503错误,我上文解释为拒绝 访问,其实更加准确的回答应该是服务不可用,那么为什么我会说503错误在高并发的情况下90%的原因是数据库所致呢?上文我做出了详细的解释,但是今天 我回味了一下,发现那个解释还不是太突出重点,问题的重点是在高并发的情况整个网站系统首先暴露出问题的是数据库,如果我们把整个网站系统比作一个盛水的木桶,那么木桶最短的那个板就是数据库了,一般而言网站的服务应用出问题都会是解决存储问题之后才会出现。 数据库出现了瓶颈并不是程序存在逻辑性错误,数据库瓶颈的表现就是数据库因为承受了太多的访问后,数据库无法迅速的做出响应,严重时候数据库会拒绝进一 步操作死锁在哪里不能做出任何反应。数据库犹如一把巨型的大锁,很多人争抢这个锁时候会导致这个大锁完全被锁死,最终请求的处理就停留在这个大锁上最终导 致网站提示出503错误,503错误最终会传递到所有的客户端上,最终的现象就是全站不可用了。 上文里我讲到session共享的一个方案是将session数据存储在外部一个独立的缓存服务器里,我开始说用一台服务器做缓存服务器,后面提到如果 觉得一台服务器做缓存不安全,那么采用分布式缓存服务器例如memcached,那么这里就有一个问题了,为了保证web服务的可用性,我们会把web服 务分开部署到不同的服务器上,这些服务器都是对等关系,其中一台服务器不能正常提供服务不会影响到整个网站的稳定性,那么我们采取memcached集群 是不是可以达到同样的效果了?即缓存服务器集群中一台服务器挂掉,不会影响到用户对网站的使用了?问题的答案是令人失望了,假如我们使用两台服务器做缓存 服务器来存储session信息,那么如果其中一台服务器挂掉了,那么网站将会有一半的用户将不能正常使用网站,原因是他们的session信息丢失了, 网站无法正常的跟踪用户的会话状态。我之所以提到这个问题是想告诉大家以memcached为代表的分布式缓存和我们传统理解的分布式系统是有区别的,传 统的分布式系统都会包含一个容灾维护系统稳定性的功能,但实际的分布式技术是多种多样的,例如memcached的分布式技术并不是为了解决容灾维护系统 稳定性的模式设计,换个说法就是memcached集群的设计是没有过分考虑冗余的问题,而只有适当的冗余才能保证系统的健壮性问题。分布式技术的实现是 千差万别的,每个优秀的分布式系统都有自身独有的特点。… Read More

关于大型网站技术演进的思考(三)–存储的瓶颈(3)

存储的瓶颈写到现在就要进入到深水区了,如果我们所做的网站已经到了做数据库垂直拆分和水平拆分的阶段,那么此时我们所面临的技术难度的挑战也会大大增强。 这里我们先回顾下数据库的垂直拆分和水平拆分的定义:   垂直拆分:把一个数据库中不同业务单元的数据分到不同的数据库里。   水平拆分:是根据一定的规则把同一业务单元的数据拆分到多个数据库里。 垂直拆分 是一个粗粒度的拆分数据,它主要是将原来在一个数据库下的表拆分到不同的数据库里,水平拆分粒度比垂直拆分要更细点,它是将一张表拆到不同数据库里,粒度 的粗细也会导致实现技术的难度的也不一样,很明显水平拆分的技术难度要远大于垂直拆分的技术难度。难度意味着投入的成本的增加以及我们需要承担的风险的加 大,我们做系统开发一定要有个清晰的认识:能用简单的方案解决问题,就一定要毫不犹豫的舍弃复杂的方案,当系统需要使用高难度技术的时候,我们一定要让自己感受到这是迫不得已的。 我是以 java工程师应聘进了我现在的公司,所以在我转到专职前端前,我也做过不少java的应用开发,当时我在公司的前辈告诉我,我们公司的数据库建模很简 单,怎么个简单法了,数据库的表之间都没有外键,数据库不准写触发器,可以写写存储过程,但是存储过程决不能用于处理生产业务逻辑,而只能是一些辅助工 作,例如导入导出写数据啊,后面听说就算是数据库做到了读写分离,数据之间同步也最好是用java程序做,也不要使用存储过程,除非迫不得已。开始我还不 太理解这些做法,这种不理解不是指我质疑了公司的做法,而是我在想如果一个数据库我们就用了这么一点功能,那还不如让数据库公司为咋们定制个阉割版算了, 不过在我学习了hadoop之后我有点理解这个背后的深意了,其实作为存储数据的数据库,它和我们开发出的程序的本质是一样的那就是:存储和计算,那么当 数据库作为一个业务系统的存储介质时候,那么它的存储对业务系统的重要性要远远大于它所能承担的计算功能,当数据库作为互联网系统的存储介质时候,如果这 个互联网系统成长迅速,那么这个时候我们对数据库存储的要求就会越来越高,最后估计我们都想把数据库的计算特性给阉割掉,当然数据库基本的增删改查我们是 不能舍弃的,因为它们是数据库和外界沟通的入口,我们如果接触过具有海量数据的数据库,我们会发现让数据库运行的单个sql语句都会变得异常简洁和简单, 因为这个时候我们知道数据库已经在存储这块承担了太多的负担,那么我们能帮助数据库的手段只能是尽量降低它运算的压力。… Read More

关于大型网站技术演进的思考(四)–存储的瓶颈(4)

如果数据库需要进行水平拆分,这其实是一件很开心的事情,因为它代表公司的业务正在迅猛的增长,对于开发人员而言那就是有不尽的项目可以做,虽然会感觉很忙,但是人过的充实,心里也踏实。   数据库水平拆分简单说来就是先将原数据库里的一张表在做垂直拆分出来放置在单独的数据库和单独的表里后更进一步的把本来是一个整体的表进一步拆分成多张表,每一张表都用独立的数据库进行存储。 当表被水平拆分后,原数据表成为了一个逻辑的概念,而这个逻辑表的业务含义需要多张物理表协同完成,因此数据库的表被水平拆分后,那么我们对这张表的操作 已经超出了数据库本身提供给我们现有的手段,换句话说我们对表的操作会超出数据库本身所拥有的处理能力,这个时候我就需要设计相关的方案来弥补数据库缺失 的能力,这就是数据库水平拆分最大的技术难点所在。 数据库的 水平拆分是数据库垂直拆分的升级版,它和垂直拆分更像继承机制里的父子关系,因此水平拆分后,垂直拆分所遇到的join查询的问题以及分布式事务的问题任 然存在,由于表被物理拆解增加了逻辑表的维度,这也给垂直拆分里碰到的两个难题增加了更多的维度,因此水平拆分里join查询的问题和分布式事务会变得更 加复杂。水平拆分除了垂直拆分两个难题外,它还会产生新的技术难题,这些难题具体如下:   难题一:数据库的表被水平拆分后,该表的主键设计会变得十分困难;   难题二:原来单表的查询逻辑会面临挑战。 在准备本篇文章时候,我看到一些资料里还提到了一些难题,这些难题是:   难题三:水平拆分表后,外键的设计也会变得十分困难;   难题四:这个难题是针对数据的新增操作的,大致的意思是,我们到底按什么规则把需要存储的数据存储在拆分出的那个具体的物理数据表里。 难题三的 问题,我在上篇已经给出了解答,这里我进行一定的补充,其实外键问题在垂直拆分就已经存在,不过在讲垂直拆分时候我们没有讲到这个问题,这主要是我设定了 一个前提,就是数据表在最原始的数据建模阶段就要抛弃所有外键的设计,并将外键的逻辑抛给服务层去完成,我们要尽全力减轻数据库承担的运算压力,其实除了 减轻数据库运算压力外,我们还要将作为存储原子的表保持相对的独立性,互不关联,那么要做到这点最直接的办法就是去掉表与表之间关联的象征:外键,这样我… Read More

关于大型网站技术演进的思考(五)–存储的瓶颈(5)

上文里我遗留了两个问题,一个问题是数据库做了水平拆分以后,如果我们对主键的设计采取一种均匀分布的策略,那么它对于被水平拆分出的表后续的查询操作 将有何种影响,第二个问题就是水平拆分的扩容问题。这两个问题在深入下去,本系列就越来越技术化了,可能最终很多朋友读完后还是没有找到解决实际问题的启 迪,而且我觉得这些问题都是像BAT这样巨型互联网公司才会认真思考的,因此本篇我打算换个角度来阐述本文的后续内容。   这里我们 首先要明确一个问题,到底是什么因素促使我们去做数据库的垂直拆分和水平拆分的呢?答案很简单就是业务发展的需求,前文里的水平拆分技术方案基本都是抛弃 千变万化的业务规则的限制,尽量将水平拆分的问题归为一个简单的技术实现方案,而纯技术手段时常是看起来很美,但是到了面对现实问题时候,常常会变得那么 苍白和无力。   水平拆分 的难题里我还有个难题没有讲述,就是水平拆分后对查询操作的影响,特别是对单表查询的影响,这点估计也是大伙最为关心的问题,今天我不在延着水平拆分的技 术手段演进是阐述上文的遗留问题,而是我要把前面提到的技术手段和一些典型场景结合起来探讨如何解决网站存储的瓶颈问题。   前文中我总结过一个解决存储瓶颈的脉络,具体如下:   单库数据库–>数据库读写分离–>缓存技术–>搜索技术–>数据的垂直拆分–>数据的水平拆分   这个脉络给一些朋友产生了误解,就是认为这个过程应该是个串行的过程,其实在实际的场景下这个过程往往是并行的,但是里面有一个元素应该是串行的或者说思考时候有个先后问题,那就是对数据库层的操作,具体如下:   单库数据库–>数据库读写分离–>数据的垂直拆分–>数据的水平拆分… Read More

关于大型网站技术演进的思考(六)–存储的瓶颈(6)

在讲数据库水平拆分时候,我列出了水平拆分数据库需要解决的两个难题,它们分别是主键的设计问题和单表查询的问题,主键问题前文已经做了比较详细的讲述了,但是第二个问题我没有讲述,今天我将会讲讲如何解决数据表被垂直拆分后的单表查询问题。   要解决数据表被水平拆分后的单表查询问题,我们首先要回到问题的源头,我们为什么需要将数据库的表进行水平拆分。下面我们来推导下我们最终下定决心做水平拆分表的演进过程,具体如下:     第一个演进过程:进行了读写分离的表在数据增长后需要进行水平拆分吗?回答这个疑问我们首先要想想进行读写分离操作的表真的是因为数据量大吗?答案其实是否定的。最基本的读写分离的目的是为了解决数据库的某张表读写比率严重失衡的问题, 举个例子,有一张表每天会增加1万条数据,也就是说我们的系统每天会向这张表做1万次写的操作,当然也有可能我们还会更新或者删除这张表的某些已有的记 录,这些操作我们把它归并到写操作,那么这张表一天我们随意定义个估值吧2万5千次写操作,其实这种表的数据量并不大,一年下来也就新增的几百万条数据, 一个大型的商业级别的关系数据库,当我们为表建立好索引和分区后,查询几百万条数据它的效率并不低,这么说来查询的效率问题还不一定是读写分离的源头。其 实啊,这张表除了写操作每天还承受的读操作可能会是10万,20万甚至更高,这个时候问题来了,像oracle和mysql这样鼎鼎大名的关系数据库默认 的最大连接数是100,一般上了生产环境我们可能会设置为150或者200,这些连接数已经到了这些关系数据库的最大极限了,如果再加以提升,数据库性能 会严重下降,最终很有可能导致数据库由于压力过大而变成了一个巨锁,最终导致系统发生503的错误,如是我们就会想到采用读写分离方案,将数据库的读操作 迁移到专门的读库里,如果系统的负载指标和我列举的例子相仿,那么迁移的读库甚至不用做什么垂直拆分就能满足实际的业务需求,因为我们的目的只是为了减轻 数据库的连接压力。     第二个演进过程: 随着公司业务的不断增长,系统的运行的压力也越来越大了,我们已经了解了系统的第一个瓶颈是从存储开始了,如是我们开始谈论方案如何解决存储的问题,这时 我们发现我们已经做了读写分离,也使用了缓存,甚至连搜索技术也用上了,那么下个阶段就是垂直拆分了,垂直拆分很简单就是把表从数据库里拆出来,单独建库 建表,但是这种直截了当的方案想想就能感到这样的做法似乎没有打中系统的痛点,那么系统的痛点到底是什么呢?根据数据库本身的特性,我们会发现痛点主要是… Read More

关于大型网站技术演进的思考(七)–存储的瓶颈(7)

本文开篇提个问题给大家,关系数据库的瓶颈有哪些?我想有些朋友看到这个问题肯定会说出自己平时开发中碰到了一个跟数据库有关的什么什么问题,然后如何 解决的等等,这样的答案没问题,但是却没有代表性,如果出现了一个新的存储瓶颈问题,你在那个场景的处理经验可以套用在这个新问题上吗?这个真的很难说。   其实不管什么样的问题场景最后解决它都要落实到数据库的话,那么这个问题场景一定是击中了数据库的某个痛点,那么我前面的六篇文章里那些手段到底是在解决数据库的那些痛点,下面我总结下,具体如下:      痛点一:数据库的连接数不够用了。换句话说就是在同一个时间内,要求和数据库建立连接的请求超出了数据库所允许的最大连接数,如果我们对超出的连接数没 有进行有效的控制让它们直接落到了数据库上,那么就有可能会让数据库不堪重负,那么我们就得要分散这些连接,或者让请求排队。      痛点二:对于数据库表的操作无非两种一种是写操作,一种是读操作,在现实场景下很难出现读写都成问题的事情,往往是其中一种表的操作出现了瓶颈问题所引 起的,由于读和写都是操作同一个介质,这就导致如果我们不对介质进行拆分去单独解决读的问题或者写的问题会让问题变的复杂化,最后很难从根本上解决问题。      痛点三:实时计算和海量数据的矛盾。本系列讲存储瓶颈问题其实有一个范畴的,那就是本系列讲到的手段都是在使用关系数据库来完成实时计算的业务场景,而 现实中,数据库里表的数据都会随着时间推移而不断增长,当表的数据超出了一定规模后,受制于计算机硬盘、内存以及CPU本身的能力,我们很难完成对这些数据的实时处理,因此我们就必须要采取新的手段解决这些问题。   我今天之所以总结下这三个痛点,主要是为了告诉大家当我们面对存储瓶颈问题时候,我们要把问题最终落实到这个问题到底是因为触碰到了数据库的那些痛点,这样回过头来再看我前面说到的技术手段,我就会知道该用什么手段来解决问题了。   好了,多余的话就说到这里,下面开始本篇的主要内容了。首先给大伙看一张有趣的漫画,如下图所示: 身为程序… Read More

关于大型网站技术演进的思考(八)–存储的瓶颈终篇(8)

在开始本篇主要内容前,我们一起看看下面的几张截图,首先是第一张图,如下图所示: 这是一家电商网站的首页,当我们第一次打开这个首页,网站会弹出一个强制性的对话框,让用户选择货物配送的地址,如果是淘宝和京东的话,那么这个选择配货地址的选项是在商品里,如下图是淘宝的选择配送地点: 下图是京东选择配货地点: 那么图一 跟京东和淘宝有什么区别呢?图一的电商强制用户选择地区后,那么我们在查询这个商品时候会因为地区不同,显示的查询结果会不一样,这个就和网站做国际化有 点像,不过网站国际化是切语言和语言相关的静态资源,但是电商这个地域的选择是和业务相关的,不同的地域查询结果是不相同的,这个选择地域的弹出框很像一 个路由器。相比之下,淘宝和京东把商品的配送和商品相关,那么我们在这些网站里查询商品时候,其实是按照全国查询的,全国不同的地方查询同一个条件所获得 到的结果是一致的。从业务角度而言,这说明第一个电商的业务没有全国铺开,就算是铺开了,地域的差异也影响到物流的问题,而淘宝和京东则正是一个全国意义 的大型电商网站了。   回到技术的角度,这两种不同的做法有没有可能还和技术问题有关了?今天我就来探讨下这个问题。   不管网站 大与小,一个网站肯定可以分为客户端、服务端和存储端,勾连这不同的组成部分是网络,网络是一种通讯设施,距离的远近会直接影响到网络传输的效率问题,如 是乎就出现了像CDN这样的技术,很多大型互联网公司还会在不同的城市建立机房,这些手段的目的就是在解决距离对网络传输效率的影响,但是当这种就近解决 问题的方案落到存储层的时候,问题就来了。上篇里我说道web服务的水平扩展问题,这种水平扩展是基于一种无状态性的原理设计的,但是到了存储层我们不管 怎么拆分它,它都很难消除状态的问题,也就是存储层有状态性是它的天然属性。特别是碰到一个竞争性的存储资源时候,这种状态性会变得非常顽固,例如商品的 库存问题,如果我们把库存数据对等的平移到不同地域的数据中心,那么如何保证不同地方的库存信息总是准确的,这就成为了难题。这种问题放在一个小国家不是… Read More

jQuery实现的测试答题功能

有时在网页中要加入一个在线测试功能,例如在线调查,在线测试各类知识等应用,这类应用需要用到很多前后端技能。今天我给大家分享一个基于jQuery的前端应用——测试答题功能。 查看演示 下载源码 HTML 首先载入jquery库文件和quiz.js以及所需的CSS样式文件styles.css。 <script src="jquery.js"></script> <script src="quiz.js"></script> <link rel="stylesheet" href="styles.css" /> 然后在需要放置测试题的位置加入div#quiz-container。 <div id="quiz-container"></div> jQuery 首先,我们定义题目和答案选项,question是题目,answers是答案选项,correctAnswer是正确答案。可以看出定义的init是一个json数据格式。… Read More

HTML5获取地理位置定位信息

HTML5提供了地理位置定位功能(Geolocation API),能确定用户位置,我们可以借助HTML5的该特性开发基于地理位置信息的应用。本文结合实例给大家分享如何使用HTML5,借助百度、谷歌地图接口来获取用户准确的地理位置信息。 查看演示 下载源码 如何使用HTML5地理位置定位功能 定位功能(Geolocation)是HTML5的新特性,因此只有在支持HTML5的现代浏览器上运行,特别是手持设备如iphone,地理定位 更加精确。首先我们要检测用户设备浏览器是否支持地理定位,如果支持则获取地理信息。注意这个特性可能侵犯用户的隐私,除非用户同意,否则用户位置信息是 不可用的,所以我们在访问该应用时会提示是否允许地理定位,我们当然选择允许即可。 function getLocation(){ if (navigator.geolocation){ navigator.geolocation.getCurrentPosition(showPosition,showError); }else{ alert("浏览器不支持地理定位。"); } } 上面的代码可以知道,如果用户设备支持地理定位,则运行… Read More

PHP+jQuery+MySql实现红蓝投票功能

这是一个非常实用的投票实例,应用在双方观点对抗投票场景。用户可以选择支持代表自己观点的一方进行投票,本文以红蓝双方投票为例,通过前后台交互,直观展示红蓝双方投票数和所占比例,应用非常广泛。 查看演示 下载源码 本文是一篇综合知识应用类文章,需要您具备PHP、jQuery、MySQL以及html和css方面的基本知识。本文在《PHP+MySql+jQuery实现的“顶”和“踩”投票功能》一文基础上做了适当改进,共用了数据表,您可以先点击了解这篇文章。 HTML 我们需要在页面中展示红蓝双方的观点,以及对应的投票数和比例,以及用于投票交互的手型图片,本例以#red和#blue分别表示红蓝双 方。.redhand和.bluehand用来做手型投票按钮,.redbar和.bluebar展示红蓝双方比例调,#red_num 和#blue_num展示双方投票数。 <div class="vote"> <div class="votetitle">您对Helloweba提供的文章的看法?</div> <div class="votetxt">非常实用<span>完全看不懂</span></div> <div class="red" id="red"> <div… Read More

HTML5 Geolocation API : 实时跟踪应用

getCurrentPosition与watchPosition   watchPosition会监视你的移动,并在位置改变时向你报告位置。watchPPosition方法看上去确实与getCurrentPosition方法很像,不过行为稍有不同,每次位置比阿奴啊时会重复调用你的成功处理程序 watchPosition调用步骤: 你的应用watchPosition,传入一个成功处理函数 watchPosition在后台不断监视你的位置 你的位置改变时,watchPostion调用成功处理函数来报告你的新位置 watchPostion继续监视你的位置(并向成功处理程序报告),直至你调用clearWatch将它清除   HTML代码   我们已HTML5COL学院中级课程相关章节的课程为基础,再向HTML增加几个按钮,从而能开始和结束跟踪你的位置;我们设置开始按钮是因为用户不想一直被跟踪,他们通常希望对此有些控制;设置结束按钮,是考虑到对于移动设备来说,不停检查用户的位置是一个相当耗费电的操作,如果一直打开跟踪,会严重影响电池寿命: 注: 实时跟踪用户可能非常耗电。一定要为用户提供信息,指出日前正在跟踪,另外还要提供相应的一些控件 <!DOCTYPE html> <html> <head>… Read More