整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

实现一个靠谱的Web认证

实现一个靠谱的Web认证

eb认证是任何一个认真一点的网站都必须实现的基本功能。这个功能解决了让服务器“认识你就是你“的问题。这个功能看起来貌似很简单,但是实际上处处是坑。因为认证是依靠一套技术整体运作才能完成,所以仅仅是把一些现成的技术简单拼起来是不够的。你必须了解每一种技术能做什么,不能做什么,解决了哪些问题,才能精心设计一套认证功能。

两种认证

目前市面上能见到的认证方式分为两大种——基于Session的和基于Token的。

所谓基于Session的认证,是指在客户端存储一个Session Id。认证时,请求携带Session Id,并由服务器从Session数据存储中找到对应的Session。这种方式在很多网站框架下都有

所谓基于Token的认证,是指将所有认证相关的信息在服务器端编码成一个Token,并由服务器签名,以确保不被篡改。Token本身是明文的。存在Token里的信息可以有比如user id、权限列表、用户昵称一类的。这样服务器只要拿着token和token的签名,就可以直接验证用户的身份是合法的。在现实当中,基于Token的认证的主要标准是Json Web Token (JWT),见RFC 7519。

认证方式

但是我不得不说的是,基于Token的认证在现实当中并不是很实用……

JWT

一个JWT大概长这样:

base64(header).base64(json payload).signature
  • header部分描述一些基本信息,比如这个token是用什么算法签名的,是什么版本的等等。
  • payload就是一个json object。你可以任意放置你想要的信息,只要符合json的格式即可。标准中已经规定好了有一些字段的意思,比如iat表示issue at,token签发的时间;exp表示token过期的时间等等。根据这些约定就可以实现一些小的代码库来检查比如token是不是过期了等等。但是请注意,很多人误解,认为JWT是加了密的,但其实payload是明文的
  • signature是一个签名。服务器端可以自行选择一个算法和一个secret,与payload拼接上,得到一个签名。secret并不会在网络中传输,所以客户端无法伪造一个JWT。这样,一旦一个签名生成,再传回给服务器,服务器就可以知道这个token是不是它当初生成的。

通过这样的机制,JWT中可以存储一些认证必要的信息。给定一个JWT,服务器只要验证:

  • 这个JWT的签名是对的
  • 这个JWT还在生效(即当前时间在JWT生效时刻之后,在失效时刻之前)

之后服务器就可以信任这个JWT中包含的信息,包括user id、包含的权限等等。服务器不需要自己再去查询一遍这个用户的信息,以及这个用户的权限信息,就可以对请求作出相应。不用session了,无状态大法好!然而,需要泼一下冷水的是:

  • 使用了JWT,无法实现在服务器端对用户请求进行管理——管理员没法统计多少个人登录了,一个人登录了多少次,登陆了什么设备;同时,也无法强行“踢”掉一个用户的登录——JWT一旦生成,在失效之前,总是有效的。如果实现了一个token黑名单之类的功能,就等价于实现了Session机制,无状态带来的好处就无从谈起。这个限制对于任何一个要认真做用户风险控制的网站来说都是不可能接受的。
  • 使用了JWT,无法很好的控制payload的数据量。尽管规范表示,应该只把认证的相关信息放到payload里。但实际上,开发人员往往会误用,把几乎所有和user相关的数据都放到payload里。而payload的尺寸过大,比如达到数KB,就会极大的损耗带宽和IO性能。要记得,为了达成“无状态”,每个请求都必须把全量的JWT都带着……

这两个严重的缺陷限定了JWT只能用到一些不太认真的场景。而对于真正的社交、金融、游戏等认真一点的服务,还是要选择基于Session的认证。

当然,token中的签名还是有好处的,签名可以确保token的确是服务器产生的,不会被篡改。如果token中包含了user id,那么还可以实现简单的前端错误上报;如果token中还有session id,就可以在服务器端实现基于Session的认证。因此,你可以将user id、session id、token过期时间等几个关键数据放到payload里——只放这几个,不放其他的数据,得到一个用来做Session认证的JWT。更进一步,如果你把JWT的规范稍微小改一下,比如payload不用JSON,而是更紧凑的格式;定死了签名算法,即可省略JWT的header了;最后再优化一下编码格式,就能得到一个你自己的token。

但,无论用session还是token,还是什么其他的名字,这些都不重要。重要的是服务器这边必须实现session机制,以便于对用户登录信息进行有效的管理。

有人告诉过我一个使用基于Token + 无状态的认证方式的原因:他们的存储是一个云服务,并且按照调用次数收费。所以他们让用户每次将Token传给服务器,就是希望尽量少的调用那个云服务。对此我表示很无语……

怎么存储认证信息

谈完了session和token,我们来说所说这个信息在客户端怎么存储。客户算也分两大类——浏览器和Native App。先说说浏览器。

浏览器

浏览器中的存储主要是Local Storage和Cookie。

其实浏览器用于存放认证信息的存储还有Session Storage,但是它和Local Storage差不多,只是失效的机制不太一样。这里只用Local Storage讨论。

使用基于Token认证的开发人员很喜欢使用Header + Local Storage。因为这样可以有效防止CSRF (下一小节专门讲)。

但是使用Local Storage,反而会增加中招XSS(Crossing Site Script)的机会。一旦中招XSS,攻击者可以轻易的拿到认证信息,并且传回自己的接受网址而不被用户察觉。这样一来攻击者能够轻易的代替用户登录了。

整个浏览器中,只有一种资源是脚本无法访问到的。这就是被设置为HttpOnly的cookie。这是非常理想的放置认证token/session id的地方。设置这种token只需要在Set Cookie时这么写:

Set-Cookie: access_token=xxxxxxxxxxxxxxxxxx; HttpOnly; Secure; Same-Site=strict; Path=/;

(Secure和Same-Site是什么?下文会解释)

XSS攻击者没有任何办法从HttpOnly的Cookie中拿到你的认证信息,除非他能在你登录网站后,直接进入你的电脑,打开浏览器的开发者工具并人肉复制粘贴(叫你不锁屏,哼)。

有些人坚称自己的程序可以保证不受XSS的攻击,所以可以放心的用Local Storage。比如使用React框架开发的程序理论上所有的DOM节点都由React的虚拟DOM产生,所有的标签生成都进行了escape。espace掉的脚本就无法执行,也就不可能XSS了。

这样讲没有错误,但是XSS最令人头疼的地方在于你很难保证你的网站对所有用户的输入都进行了escape。

  • 你编写的是一个写文章的网站,需要支持用户手工输入HTML,并且HTML必须得直接展示;
  • 你编写的网站99%是React这样的框架生成的,但是可能会有一些边角,为了方便还是使用jquery等传统技术
  • 你的网站是一个团队开发,尽管开发规范要求大家都要对用户的输入进行escape处理,但是只要是人就会忘,而escape这件事情不一定能进入到测试的Case清单;
  • ……

只要有一个漏洞存在,那么整个防护体系就完全失效。这就是为什么HttpOnly Cookie这样的绝对隔离措施很关键的原因。

Native App

Native App比浏览器相对简单。一般Native App都是静态编译产生,不存在XSS的问题。同时移动操作系统都会有沙箱机制,避免其他App读取到自己的数据(除非你root了……)。因此,Native App可以比较放心的将数据存在App沙箱内某个存储即可。如果不放心,可以考虑如iOS KeyChain或者Android KeyStore这样的设施。

但Native App与服务器交互有一些区别。Native App一般是不直接支持Cookie机制的。所以如果一个服务器端使用Cookie来保存认证信息,就需要Natvie App手工解析Set-Cookie Header,同时,Native App因为不直接支持Cookie,所以倾向于在请求中使用AuthorizationHeader来传入认证信息。这也需要服务器适配。当然,最简单的办法是让Native App引入一个模拟Cookie行为的库。

防止CSRF

CSRF代表Crossing Site Recource Forge。大致的触发流程是:

  1. 用户登录了站点A,并且在Cookie中留下了A站点的认证信息
  2. 用户进入了站点B,而站点B用一些方式(比如一个提交行为是到A站点某关键接口的表单)引诱用户去点击。当用户点击时,会发出到A站点的请求。而浏览器会给这个请求附带上A站点的认证信息,从而让这个请求能够执行。这种行为可能是,但不限于,给某个A站点的某个其他用户提权/转账/发文辱骂等等。

上文中提到了,很多人用JWT+Local Storage的本心是为了防护CRSF。这样做的原因是——因为Cookie的发送是完全由浏览器控制的,不受网页本身的控制。所以最简单直接的办法,就是不用Cookie,不让自动发送认证信息成为可能。问题在于,这么干是有XSS风险的。从上文中可以看到,为了避免XSS,就必须用HttpOnlyCookie。

那么怎么在使用Cookie的同时,还能防范CSRF呢?

传统页面Web网站

在传统页面Web网站中,一般会使用CSRF Token。这是个非常流行的做法。像Tomcat这类的容器都会自带CSRF Token的产生和检查Filter。

CSRF Token是这样工作的。客户端要首先向服务器请求一个带有提交表单的页面,服务器返回的页面中会嵌入一个CSRF Token。当用户提交表单时,CSRF Token会被一起携带发给服务器做验证。所以当服务器看到CSRF Token,就可以放心大胆的确认用户的的确确是看看到了提交前的表单界面,从而避免了用户稀里糊涂提交一个被伪造的表单的可能性。

SPA

CSRF Token只适合于传统的页面请求,在SPA的情况下会比较尴尬。

在SPA中,客户端与服务器之间的交互主要是通过接口完成的,没有页面的概念。此时,你的确可以照猫画虎的做一个接口让用户拿到CSRF Token,但这样什么也确认不了。因为攻击者可以调用同样的接口,拿到合法的CSRF Token。

这时有几种办法:

  • 给所有接口都添加一个请求secret,来标记其来自于合法的客户端。这个secrect可以是固定的随机字符串,也可以通过某些动态算法产生。对于CSRF,浏览器只会做自动传Cookie而已,并不能帮助传入secret。这样一来,就可以确定消除CSRF的风险。但注意,这个机制仅能防范CSRF,而不能防范人为的攻击。黑客只要拿得到客户端,就一定能找到生成secret的办法。
  • secret有一个顺带的功能是提高了第三方用户随意调用接口的门槛——他们必须得去查看客户端源代码,学会了怎么生成secret才能调用接口。
  • 用Same-Site Cookie。回到上面CSRF步骤的第二步骤。当用户看到了B站点伪造的表单,点击了提交,向站点A发出请求时,被标记了Same-Site=strict的Cookie是不会被携带的,因为当时的主站点域名B和提交的站点域名A不一样。这是Same-Site=strict标记是个相对较新的标准。目前大部分浏览器都已经支持了。但如果大量的用户群还在类似于IE8这样的老系统上,这个招数便是无效的。
  • 歪招,总是用json格式提交。CSRF可能发生的一个前提条件是必须用传统表单提交。这是因为传统表单提交可以跨域——你在站点B,可以提交表单给站点A。而Ajax的请求除非开启CORS,是不允许跨域的,所以天然的屏蔽掉了这个问题。传统表单的提交的格式必然是application/x-www-form-urlencoded。因此只要保证服务器能够拒绝处理所有application/x-www-form-urlencoded格式的POST请求,就能确保SPA不受CSRF的影响。那用啥呢?JSON - application/json。(我专门写这一条的原因是,jquery的ajax库的默认行为正是使用application/x-www-form-urlencoded格式。如果你还在用,可以考虑改一下。)
  • 另一个歪招,双认证。将你的认证信息同时放在HttpOnly Cookie和Authorization Header。服务器要先比对这两个值是一样的,然后再去执行认证过程。这样可以同时防范XSS和CSRF。代价是,如果你的认证信息比较长,会浪费一些带宽。

总是使用https

大学上网络课时,老师讲解了http的一些原理,然后给我们留了个作业——去外边提供WIFI的餐厅用嗅探器扒别人的密码。两周后,我们做完了作业,心情是悲催的——尼玛互联网都发明了十几年了,连最基本的防护都没有……

http是明文传输的。在http下,用户输入的任何信息,从他的电脑到服务器之间的每个链路节点都是明文的。在这里个链路中的任何地方,都可以截取到完整的数据,包含你的密码,认证token……

这就是为什么https是必须的。https主要提供三个保证:

  • 端端加密。通过https交互的原始数据,只有用户的浏览器和最终的服务器可以看到。其他中间节点无法获)。
  • 客户端可以认定要访问的服务器就是那个服务器。这是被证书体系所支撑的。一旦浏览器的地址栏出现了网址的证书信息,并且是绿色的提示,那么用户的心里就可以稳了。(当然国内其实也不完全是这样,讲多了查水表,懂者自懂)。
  • 服务器可以认定访问的客户端就是合法的客户端。这种模式被称为“2-Way SSL”或者“Mutal SSL”。这种模式是可选的,需要多配置一个客户端证书,一般场景用不到,多见于企业Web服务。

早些时候,很多人对https有一些抵触,大致的原因是,支持https需要软件改造;服务器对证书进行密码学运算要耗费很多CPU;同时也会带来跟多的网络请求和响应(多了ssl握手)。这无疑会带来一些成本和体验上的问题。但那已经是10多年前的事情了。现在的软硬件处理能力和网络基础设施比起10年前都有数倍的提高。如果今天,一个商业网站仍然坚持不用https,那么可以请他的老板去大街上裸奔。

使用了https后,为了进一步保证安全,将Cookie设置为Secure。这样,浏览器就可以只在访问https网址时才会携带Cookie。如果不做这样的设置,通过https站点设置的Cookie,仍然会向http站点发送。当这个站点的域名解析被劫持,就可能造成向一个伪造的服务器发出你的认证信息。

认证信息不应该永久有效

很多人为了“用户体验”,选择让一个登录永久有效。这样做是非常危险的。因为一旦用户的认证信息被别人获取了,就永久性的失去了防御的机会(记得上面说的不锁电脑屏幕的后果吗?)。

因此,总是要保证认证信息的有效期是有限的。一般根据业务场景的安全级别不同,可以设为若干分钟~若干天。就算是社交娱乐类的应用,有效期最好也不要超过两周。

但,为了让频繁使用的用户体验更好,可以考虑实现会话期续期。但需要注意,这里说的续期是指从用户角度看可以延续其不需要登录的时间长度,而不是直接让session/token有效期变长。必须实现为给用户替换一个新的session id/token。这样做,既能保证同一个认证信息不会永久有效,又能让正常的、频繁使用的用户免除登录之苦。

总结一下

总结下来,一个靠谱的Web认证应该:

  • 可以使用Session也可以使用Token做认证,但是总是要保证服务器端可以管理Session,通过Session是否存在来最终确定认证的有效性;
  • 将认证信息存放在标记为HttpOnly,Secure,Same-Site=strict的Cookie中,从而避免XSS和CSRF;
  • 总是使用https,只要你的网络链路经过了公网;
  • 如果是传统的页面网站,请使用CSRF Token机制;
  • 如果可以,做一个简单的请求secret,可以辅助防止CSRF,也可以稍稍的提高接口被爬取的门槛;
  • 如果是SPA应用,放心大胆的禁用对application/x-www-form-urlencoded的支持
  • 保证token/session必须有一个有效期

如果你也觉得靠谱,就不妨照着做。

作者:大宽宽

链接:https://www.jianshu.com/p/805dc2a0f49e

 网站是怎么认证的?很多正规企业的官网是如何认证的?现在我来告诉大家正确的认证方式,免费别想了,花钱也不一定可以上,这是多家国家权威机构交互审核严格的保障,防止虚假,钓鱼,同行业等等网站恶意竞争对网民造成的侵害,提升公司网站的品牌辨识度以及信誉度,为企业官网树立可信形象,为企业在互联网上增加合作的几率。

  在我们生活中,如果一个人无法得到别人的信任,那么将失掉他在别人心中的信誉,如果一个企业无法得到消费者的信任,那么它将没办法持久生存下去。映射到互联网时代,如果一个企业不能赢得消费者的信任,那么,网上交易将无法进行,企业也将失去品牌的信誉。因此,如何在缤纷错杂的互联网环境中,让你的客户快速信任你,将是互联网企业在未来发展中面对的首要问题,而专业的网站认证即是解决这一难题最为便捷的通道。

  专业认证机构彰显网站权威

  网站认证是指第三方权威机构对互联网网站进行的网站真实身份及相关信息认证。资质齐全、信用良好的企业会获得相应的证书及相关认证图标,企业可以将其放在网站的最下方,以此向用户展示自身良好的信誉,网民也可以通过点击图标浏览详细的网站资料,更方便的识别网站的真伪,放心交易。

  目前来看,进行网站认证的权威机构包括国家工信部、中国电子信用管理中心、中国电子商务协会等,此外,一些经由认证机构审核认可的第三方网站诚信验证服务机构也以其专业权威性,帮助万千企业进行网站认证,提升网站的信誉度,比如中万网络等。

  目前国内复杂的网络安全状况,催生了许多不同的网站认证形式,他们有着不尽相同的认证机构,也有着不同的认证流程和展示方式,接下来中万网络就为您详细介绍一下。

  1)北龙中网—可信网站认证

  可信网站认证是由北龙中网推出的网站真实身份验证服务。它通过对网站实体信息进行核对来验证网站的身份。通过可信网站认证的企业也会得到“可信网站”认证的标识,并展示在网站,用户可以通过点击图标到达验证页面,查看网站的认证及安全信息。

  另外,可信网站认证也可以在还可以在搜狗搜索引擎、必应搜索引擎、神马搜索引擎提示此网站通过中网可信网站认证。搜狗浏览器、遨游浏览器、uc浏览器、114浏览器地址栏v标安全展示中得到展示。

可信网站认证:http://rz.zw.cn/kxwz.html

  2)中国电子商务协会—诚信网站认证

  诚信网站”认证评价为工信部、商务部、国资委、发改委权威认定,中国电子商务协会具体监督和指导的第三方网站真实身份认证服务,是全国最具权威的政府性网站认证;认证通过后企业会得到相关的认证标识,并以一个红色诚信网站图标的形式展示在网站最下方的醒目位置,用户亦可通过点击图标查看该网站的认证信息及安全信息。

  而且会在中国电子商务协会“企业诚信数据库系统中”,拥有一个全国最具权威和唯一性的 “企业诚信档案编号”。可以有效保护企业网站不被钓鱼、复制和盗用,该系统包含了所有经过国家ICP备案和经过诚信网站认证的企业网站信息。 此外,它还具备"网站运行监护、网页篡改监护、木马病毒监控"等网站安全服务,快速消除用户所担心的网络安全等问题。

诚信网站认证:http://rz.zw.cn/cxwz.html

  3)安全联盟—安全联盟认证

  安全联盟认证是由中国电子商务协会指导,安全联盟推出验证网站真实身份的第三方认证服务。网站通过验证后,安装安全联盟认证Logo代码,安全联盟logo一般放在网站下方醒目位置上,以一个图标的形式出现,用户点击这个图标可以连接到安全联盟的服务器上,查看该网站的验证信息,可接受全国用户公开查询。

  网站还可以在qq聊天窗口发网址绿色v标展示(提示官方认证可放心访问)。在搜狗浏览器、YY浏览器、QQ浏览器地址栏v标安全展示(提示通过安全联盟认证,可放心访问),腾讯手机管家和搜狗号码通来电展示。有效提升网站信誉,在维护网站信誉的同时,也为广大网友建立一个安全可靠的互联网环境。

安全联盟认证:http://rz.zw.cn/aqlm.html

  4)赛门铁克(Symantec)-ssl服务器证书

  赛门铁克(Symantec)是目前全球最大的SSL证书品牌,其提供的产品也都是目前业界领先的加密技术,能够为不同的网站和服务器提供安全有效地解决方案。SSL证书对于金融证券、银行、以及网上商城等涉及交易支付、客户隐私隐私信息和账号密码的网站来说是非常重要的。

  ssl证书通过在客户端浏览器与WEB服务器之间建立一条SSL安全通道,其作用就是对网络传输中的数据进行记录和加密,防止数据被截取或窃听,从而保证网络数据传输的安全性,保障了网站与客户之间的信息传递安全。

ssl证书申请:http://rz.zw.cn/ssl.html

  5)商务部-商务部AAA企业信用等级评价

  企业信用评级是企业信用评级是评级机构按照一定的方法和程序在由商务部、国资委联合推行的行业信用等级评价工作,是由专业的对企业进行全面了解、考察调研和分析的基础上,做出有关其信用行为的可靠性、安全性程度的评价,并以专用符号或简单的文字形式来表达的一种信用服务,企业信用评级能够客观公正地反映受评对象按合同约定如期履行债务或其他义务的能力和意愿。

  企业信用评级的等级划分为AAA、AA、A、B、C三等五级,其释义和计分标准。必要时,可将B、C两等级再扩展为BBB、BB、B和CCC、CC、C六级,即三等九级;还可对每个信用级别用“+”、“-”进行微调,表示略高或略低于本等级。企业信用等级直接反应一个企业的整体诚信形象,目前国内各省市在项目招投标投标、融资贷款、政府采购、企业宣传等,均要求企业出具信用等级证书、资信等级证明、信用报告,企业信用评价报告起到加分的效果。

商务部AAA企业信用等级评价:http://rz.zw.cn/bcp_xypj.html

  6)百度-百度信誉v认证

  百度信誉V认证也称百度信誉档案。是通过对互联网商家网站及网站背后的经营实体的资质、真实性认证、可信行为、消费承诺意愿、口碑评价等数据的集合,以信誉评级和信誉成长值等方式,把网站的综合信誉情况呈现给网民,作为网民决策的参考依据;从而为商家提供的一套综合的诚信背书产品,同时通过展示诚信背书,以帮助网民快速识别权威优质网站,防止山寨网站、钓鱼虚假网站对网民的侵害,提升网民信任程度,增加商家品牌影响力与公信力。

  百度信誉V认证有V1、V2、V3这三个级别,级别越高,网站的信誉度也高, 通过“官网”字样和信誉v标不仅能够提升网站知名度,而且对网站权威性也是极大的认可,更重要的是保护品牌形象。尤其是一些电子商务、购物类网站,通过“官网”字样认证后,网民朋友购买东西会更有安全感,也会更加信赖网站。

百度信誉v认证:http://rz.zw.cn/baiduv.html

  专业认证全面维护网民利益

  虽然目前国内的网站认证依然主要以身份认证为主,但不同的认证形式也都从不同角度维护了网站的诚信及安全问题,对确定网站安全状态的良好,防止网站被他人恶意破坏有着重要作用。

  如今,随着钓鱼网站、虚假网站的出现,不少用户和企业都深陷网络诚信的困扰中,专业的网站认证不仅能够让正规合法的互联网企业更好的取信于民,更好的维护公众的合法权益。而且对全面保障电子商务行业的安全发展也有着重要意义。

  中万网络作为国内专业的第三方网站认证机构,中万网络不仅为广大互联网企业提供诚信网站认证、可信网站验证、安全联盟认证、赛门铁克ssl证书几种专业的网站认证服务,有效帮助互联网企业提升网站信用度,而且也一直秉承自身的专业性,不断开拓新产品,在帮助企业快速赢得客户信任的同时,助推整个行业的健康发展。



HTML 是什么?
htyper text markup language 即超文本标记语言。
超文本: 就是指页面内可以包含图片、链接,甚至音乐、程序等非文字元素。
标记语言: 标记(标签)构成的语言。
什么是标签:
是由一对尖括号包裹的单词构成 例如: <html> *所有标签中的单词不可能以数字开头.
标签不区分大小写.<html> 和 <HTML>. 推荐使用小写.
标签分为两部分: 开始标签<a> 和 结束标签</a>. 两个标签之间的部分 我们叫做标签体.
有些标签功能比较简单.使用一个标签即可.这种标签叫做自闭和标签.例如: <br/><hr/><input/><img/>
标签可以嵌套.但是不能交叉嵌套. <a><b></a></b>
标签的属性:
通常是以键值对形式出现的. 例如 name="nick"
属性只能出现在开始标签 或 自闭和标签中.
属性名字全部小写. *属性值必须使用双引号或单引号包裹 例如 name="nick"
如果属性值和属性名完全一样.直接写属性名即可. 例如 readonly
HTML5基本结构:
将HTML4中的DTD定义为如下结构即可,其他不变。
<!DOCTYPE HTML>
HTML5支持的两种指定页面使用的字符集的方式:
使用Content-Type指定字符集
<meta http-equiv="Content-Type" content="text/html ;charset=UTF-8"/>
直接使用charset指定字符集
<meta charset="UTF-8">
<head> 标签
<title>
<title>Title</title>
<base/>
标签为页面上的所有链接规定默认地址或默认目标。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<base href="http://p_w_picpaths.cnblogs.com/cnblogs_com/suoning/845162/"/>
<base target="_blank" />
</head>
<body>
<img src="o_s.png" alt="图片加载失败。。。"/>
<a href="http://cnblogs.com/suoning/">nick blogs</a>
</body>
</html>
# 上面这段代码中,<img>标签的src属性是一个相对路径,因为<head>中通过base标签设置了链接的默认地址,
所以img的src实际的地址是“http://p_w_picpaths.cnblogs.com/cnblogs_com/suoning/845162/o_s.png”。
同样的,<a>中只是指定了href,并未指定target属性,所以也会使用base中设置的target属性的值。
<link/>
引用外部文档,常见于引用外部样式。重要属性有三个:rel、href、type。
rel 规定文档与被链接文档之间的关系。
rel="dns-prefetch" 预先解析缓存文档中使用的域名,目的是为了提高网页访问速度。使用场景:在一个网页频繁使用其他域名资源时。
rel="shortcut icon"或rel="icon" 在收藏和标题栏上用于显示的图标。示例:<link rel="icon" href="http://p_w_picpaths.cnblogs.com/cnblogs_com/suoning/845162/o_s.png">。注意:IE浏览器只支持ico格式,为了兼容IE,图片文件采用ico格式。
rel="stylesheet" 引用外部样式表。
rel="nofollow" 用于指示搜索引擎不要追踪(爬虫抓取),减少垃圾链接。用于<a>标签,使用场景:网页不被信任或是不希望呗搜索引擎录入的网站。
href 资源的路径(相对路径/绝对路径)。
type 规定被连接文档的MIME类型,用于明确文件的打开方式。例如:.ico文件 p_w_picpath/x-icon。
<meta/>
定义关于HTML文档的元数据。 重要的属性有三个:http-equiv、name、content
http-equiv 把content属性值关联到http头部。
Content-Type(浏览器接受的文档类型,一般是text/html)
refresh(网页刷新,以秒为单位)
expires(设定网页到期时间,一旦过期,必须到服务器上重传)
<meta http-equiv="Content-Type" content="text/html ;charset=UTF-8"/>
<meta http-equiv="Refresh" content="2">
<meta http-equiv="Refresh" content="2;URL=https://www.baidu.com">
<meta http-equiv="expires" content="6 Jun 2016"/>
name 把content属性关联到一个名称。
keywords(搜索关键字,用于搜索引擎抓取信息的显示)
description(搜索到网站后显示的网页内容简描述)
author(站点制作者信息)
generator(用以说明生成工具)
name也可以根据特定的功能自定义,在新浪网中有使用360认证和搜狐认证(<meta name="360-site-verification"content="63349**********"/>、<meta name="sogou_site_verification"content="BVI*******"/>)。
<meta name="keywords" content="搜索关键字">
<meta name="description" content="简要描述">
<meta name="author" content="http://cnblogs.com/suoning">
<meta name="generator" content="用以说明生成工具">
content 定义与http-equiv或name属性相关的元信息,是必要的属性。
<body> 标签
1、块级标签和内联标签
块级标签:<p><h1><table><ol><ul><form><div>
内联标签:<a><input><img><sub><sup><textarea><span>
block(块)元素的特点
① 总是在新行上开始;
② 高度,行高以及外边距和内边距都可控制;
③ 宽度缺省是它的容器的100%,除非设定一个宽度。
④ 它可以容纳内联元素和其他块元素
inline(内联)元素的特点
① 和其他元素都在一行上;
② 高,行高及外边距和内边距不可改变;
③ 宽度就是它的文字或图片的宽度,不可改变
④ 内联元素只能容纳文本或者其他内联元素
对行内元素,需要注意如下
设置宽度width 无效。
设置高度height 无效,可以通过line-height来设置。
设置margin 只有左右margin有效,上下无效。
设置padding 只有左右padding有效,上下则无效。注意元素范围是增大了,但是对元素周围的内容是没影响的。
2、基本标签
<h1>~<h6> 标题标签.
<p>: 段落标签. 包裹的内容被换行.并且也上下内容之间有一行空白.
    style="text-indent: 2em"可以设置样式为首行缩进两个字符。
    <blockquote></blockquote>可以用来设置整个段落的缩进。
<b> <strong>: 加粗标签.
<strike>: 为文字加上一条中线.
<u>: 文字下方加下划线.
<em> <i>: 文字变成斜体.
<sup>和<sub>: 上角标 和 下角标.
<br>:换行.
<hr>:水平线.
<div>
块级标签。块级标签常用于布局,行级标签常用语显示内容。
   div的显示通常使用id或class来标识。id为唯一的标签标识,class为标签的类标识。
   div的大小是由内容来决定的,默认情况下,高度由内容的高度决定,宽度适应屏幕。
   可以容纳其他元素,是一个容器。
<span>
3、特殊符号
  > >
  < <
   空格
  " 引号
  © 版权符号
特殊符号 符号码
" " ;
& & ;
< < ;
> > ;
© ;
® ;
± ± ;
× × ;
§ § ;
¢ ;
¥ ;
· · ;
&euro ;
£ ;
&trade ;

4、<a> 超链接标签(锚标签)
重要属性有三个:href、target、name
href 超链接地址:可以是Web上任意资源,包括图片,网页,样式,脚本文件等。href="#"时,表示被链接页面就是当前页面。
target 文档打开时要显示的目标位置,属性值一般有:_blank(新窗口中打开)、_self(默认,在超链接所在的容器中打开)、_parent(在超链接的父容器中打开)、_top(整个容器中打开)、name(框架名称)。
name 锚记名称。作用:跳转到文档的某个地方。返回首页。
# 跳转网页
<a href="http://cnblogs.com/suoning" target="_blank">Nick Blogs</a>
# 跳转锚记书签名称
<a name="top"><h3>Top!</h3></a>
<div style="height: 800px"></div>
<a href="#top">top</a>
1.标签最简式
<a href="mailto:xxx@xx.com">邮件联系</a>
2.标签帮你填抄送地址
<a href="mailto:xxx@xx.com?cc=xxxx@xx.com">邮件联系</a>
3.标签帮你填暗送地址
<a href="mailto:xxx@xx.com?bcc=xxxx@xx.com">邮件联系</a>
4.暗,抄
<a href="xxxxx@xx.com">邮件联系</a>
5.标签帮你填主题
<a href="mailto:xxx@xx.com?subject=这是主题">邮件联系</a>
6.填邮件内容
<a href="mailto:xxx@xx.com?body=这是内容">邮件联系</a>
7.多址发送
<a href="mailto:xxx@xx.com,xxxx@xx.com">邮件联系</a>
# http://shang.qq.com/v3/widget.html
<a target="_blank" href="http://wpa.qq.com/msgrd?v=3&uin=630571017&site=qq&menu=yes"><img border="0" src="http://wpa.qq.com/pa?p=2:630571017:51" alt="点击这里给我发消息" title="点击这里给我发消息"/></a>
<a href="tencent://message/?uin=630571017" target="_blank"><img style="border:0px;" src=http://wpa.qq.com/pa?p=1:707321921:13></a>
# 更多图片地址如下:
# http://wpa.qq.com/pa?p=1:707321921:1
# http://wpa.qq.com/pa?p=1:707321921:2
# http://wpa.qq.com/pa?p=1:707321921:3
# http://wpa.qq.com/pa?p=1:707321921:4
# http://wpa.qq.com/pa?p=1:707321921:5
# http://wpa.qq.com/pa?p=1:707321921:6
# http://wpa.qq.com/pa?p=1:707321921:7
# http://wpa.qq.com/pa?p=1:707321921:8
# http://wpa.qq.com/pa?p=1:707321921:9
# http://wpa.qq.com/pa?p=1:707321921:10
# http://wpa.qq.com/pa?p=1:707321921:11
# http://wpa.qq.com/pa?p=1:707321921:12
# http://wpa.qq.com/pa?p=1:707321921:13
5、<img> 图形标签
行级标签,用来显示图片。
重要属性有:src、title、alt、width、height、align。
src 图片地址。
title 鼠标悬浮在图片上的文字。
alt 图片找不到时要替换的文字。如果图片资源使用的是外网资源,则不会显示要替换的文字。如果使用的是本网站的资源(相对路径给出),则找不到图片时会显示替换的文字,并保留图片设置的宽高结构。
align 图片周围文字的垂直对齐情况。常用的属性值有:top(与图片的顶部对齐)、middle(与图片的中部对齐)、bottom(默认,与图片的底部对齐)。
width 图片的宽
height 图片的高 (宽高两个属性只用一个会自动等比缩放.)
<img src="http://p_w_picpaths.cnblogs.com/cnblogs_com/suoning/845162/o_ns.png" alt="图片加载失败。。。" title="The knife girl, kiss"/>
6、列表标签 
<ul> :无序列表标签
<li>:列表中的每一项.
<ol> :有序列表标签
<li>:列表中的每一项.
<li>主要的属性有:type、value两个:
type指明项目的类型,属性值有:A,a,I,i,1,disc(实心圆),square(实心正方形),circle(空心圆)。
value表示序号值从几开始。
<dl> 定义列表
<dt> 列表标题
<dd> 列表项
<ur>
<li type="circle">A</li>
<li type="1">B</li>
<li type="1">C</li>
</ur>
<ol>
<li value="3">3</li>
<li>4</li>
</ol>
<dl>
<dt><i>标题</i></dt>
<dd>第一项</dd>
<dd>第二项</dd>
<dd>第三项</dd>
</dl>
  
7、<table> 表格标签
<table border="1">
<thead>
<tr>
<th>序号</th>
<th>姓名</th>
</tr>
</thead>
<tbody>
<tr>
<th>1.</th>
<td>nick</td>
</tr>
<tr>
<th>2.</th>
<td>jenny</td>
</tr>
</tbody>
</table>
<table> 表格标签
border:(表格边框)
align(水平对齐方式)
bgcolor(背景颜色)
cellpadding(内边距,单元格与内容之间的距离)
cellspacing(外边距,单元格的间距,设置为0时,表格变为实线表格)
width(表格的宽度,可以用%或者像素,最好通过css来设置长宽)
<caption> 表格的标题
<tr> 表格的数据行,table row
<th> 表格的表头名称,与<td>不同在于文字采用加粗居中的形式显示,table head cell
<td> 单元格,用来显示表格内容,table data cell
<thead> 表格头部,使结构更加分明
<tbody> 表格主体部分,使结构更加分明
rowspan 单元格竖跨多少行,作用在th或者td上
colspan 单元格横跨多少列(即合并单元格),作用在th或者td上
<table>
<caption>xxxxxxxxxx</caption>
<thead>
<tr>
<th>序号</th>
<th>姓名</th>
<th>年龄</th>
<th>女神</th>
</tr>
</thead>
<tbody>
<tr>
<th>1.</th>
<td>nick</td>
<td>18</td>
<td>可可西</td>
</tr>
<tr>
<th>2.</th>
<td>jenny</td>
<td>21</td>
<td>nick!!!</td>
</tr>
</tbody>
</table>
8、<form>表单标签
表单属性
HTML 表单用于接收不同类型的用户输入,用户提交表单时向服务器传输数据,从而实现用户与Web服务器的交互。表单标签, 要提交的所有内容都应该在该标签中。
属性:action、method、enctype
action 表单要提交的地址,用于处理表单的内容(一般是提交字典到后台的一个接口,这个接口是java写成的,提交到这个接口后后台就知道如何处理这些数据了)。
method 提交的方法,默认是get方式提交。
get: 1.提交的键值对.放在地址栏中url后面. 2.安全性相对较差. 3.对提交内容的长度有限制.
post:1.提交的键值对不在地址栏. 2.安全性相对较高. 3.对提交内容的长度理论上无限制.
enctype 对表单数据进行编码,默认都是要编码的。格式为:application/x-www-form-urlencoded(表单默认的编码格式,表单发送前对所有字符进行编码。编码规则:空格转换为“+”号,特殊符号转换为ASC HEX值)。提交普通的文本内容到服务器就可以采用这种默认的编码方式。当你需要提交的是一个文件时,编码就需要采用另一种格式:multipart/form-data(不对字符编码,文件上传时使用)。text/plain(是一种纯文本编码,空格转换为“+”号,但是不对特殊字符进行编码)。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="https://www.baidu.com/s">
<input type="text" name="wd">
<input type="submit" value="百度一下">
</form>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="https://www.sogou.com/web">
<input type="text" name="query">
<input type="submit" value="搜狗搜索">
</form>
</body>
</html>
表单元素
<input> type 属性:
text 文本框输入(默认text文本框类型)。
autocomplete(自动完成输入的内容,要求表单元素要有name属性才有自动完成的效果,off表示自动完成不可用,on表示自动完成可用)
disabled(设置或者获取控件的状态,默认是false即可用,等于true时不可用,不能输入内容)
    password 密码框。(以下属性text和password共有)
size(指定表单元素的初始宽度。当type为text或password时,表单元素的大小以字符为单位,对于其他元素,宽度以像素为单位)
maxlength(type为text或password时,表示输入的最大字符数),有利于防止sql的注入攻击
readonly 只读. 
      placeholder 框内预置内容(灰色),写上内容时才消失
radio 单选按钮。属性:
name(将name的值设置为相同值,才表示一组数据,才能实现单选功能)
value(必须要写,提交到服务器的key值,实际开发过程中value一般是编号)
checked(是否被选中的状态)
checkbox 复选框。
name(名字一定要一样一样的,才表示是一组数据,添加到同一value值列表提交到服务器)
value(必须要写,提交到服务器的key值,实际开发过程中value一般是编号)
checked(是否被选中的状态)
file 文件域,上传文件(不同的浏览器表现形式不同)
    submit 提交按钮。用于提交表单。
    reset 重置按钮。清空表单的输入,恢复到表单默认的状态。
button 普通按钮。一般结合javascript使用。
    p_w_picpath 图片按钮,用来提交表单,与submit是一样的效果。
src(图片路径)
    hidden 隐藏字段。
value(隐藏的内容)
    color 颜色标签。value指定颜色值(采用#十六进制数表示)。
    date 日期。value值指定默认的日期,格式为****-**-**(年月日)。
    datetime-local 显示本地时间,value值指定默认的时间,格式为2016-05-20T11:10:10(年月日T时分秒)。
    number 数字向上或者向下滑动。可以填数字然后向上或者向下选择不同的值。
    range 滑动标签。min(指定最小值)、max(指定最大值)、value(指定当前默认值)。
    week 每年的周数。value指定哪一年第几周,格式为2016-W25(2016年第25周)。
<textarea> 文本域标签。默认表现形式是可以输入很多行文本的文本框。
name (表单提交项的key)
    cols(设置文本域宽度)
rows(设置文本域高度,即行数)
<select> 下拉框标签。使用时要结合<option>子标签一起使用。
name:表单提交项的key
size:选项个数
multiple:多选
<option> 下拉选中的每一项
value(表单提交项的值)
selected(selected下拉选默认被选中)
<optgroup>为每一项加上分组
<label> 把元素与文本结合起来
友好设计:不只是选中复选框才能选中并打钩,要求点击对应的文字也能选中该复选框。
这种情况下要用到<label>标签的for属性(设置或获取给定标签对象指定到的对象,值=另一个元素的id号即可)
<label for="name">姓名</label>
<input id="name" type="text">
<fieldset> 对表单中的相关元素进行分组
<fieldset>
<legend>温馨提示</legend>
<div align="middle">不要忘记点赞哦==</div>
</fieldset>
value: 表单提交项的值
对于不同的输入类型,value 属性的用法也不同:
type="button", "reset", "submit" - 定义按钮上的显示的文本
type="text", "password", "hidden" - 定义输入字段的初始值
type="checkbox", "radio", "p_w_picpath" - 定义与输入相关联的值
框架
<frameset> 框架
用来划分窗体,不能放在<body>中,否则没有效果。
cols (纵向分割页面。其数值表示方法有三种:“30%、30(或者30px)、*”;数值的个数代表分成的视窗数目且数值之间用“,”隔开。“30%”表示该框架区域占全部浏览器页面区域的30%;“30”表示该区域横向宽度为30像素;“*”表示该区域占用余下页面空间。例如:cols="25%,200,*" 表示将页面分为三部分,左面部分占页面30%,中间横向宽度为200像素,页面余下的作为右面部分。)
rows(横向分割页面。属性和cols一样)
frameborder(设置是否显示框架边框。设定值只有0、1;0 表示不要边框,1 表示要显示边框)
border(框架之间的距离,一般设置为0)
bordercolor(边框的颜色)
framespacing(设置框架与框架间的保留的空白距离)
<frameset cols="40%,*,*"> 第一个框架占整个浏览器窗口的40%,剩下的空间平均分配给另外两个框架。
<frameset cols="*,*,*,*"> 浏览器窗口等分为四部分。
<iframe> 框架
元素会创建包含另外一个文档的内联框架(即行内框架)
name (设置框架名称。此为必须设置的属性)
src (设置此框架要显示的网页名称或路径。此为必须设置的属性)
scrolling (设置是否要显示滚动条。设定值为auto, yes, no)
bordercolor (设置框架的边框颜色)
frameborder (设置是否显示框架边框。设定值只有0、1;0 表示不要边框,1 表示要显示边框)
noresize (设置框架大小是否能手动调节)
marginwidth (设置框架边界和其中内容之间的宽度)
marginhight (设置框架边界和其中内容之间的高度)
width(设置框架宽度)
height (设置框架高度)