1、从 URL 输入到页面展现背后发生的事
1. 从 URL 输入到页面展现背后发生了什么事?
1.在浏览器输入 URL;
2.浏览器查找域名对应的 IP 地址;
第一步中,我们已经输入了相应的 URL,但浏览器本身并不能识别 URL 是什么,因此从我们输入 URL 开始,浏览器就要进行域名解析来找到对应 IP——DNS 解析是浏览器的实际寻址方式:
查找浏览器缓存——近期浏览过的网站,浏览器会缓存 DNS 记录一段时间 (如果没有则往下) ;
查找系统缓存——从 C 盘的 hosts 文件查找是否有存储的 DNS 信息,查找是否有目标域名和对应的 IP 地址 (如果没有则往下);
查找路由器缓存 (如果没有则往下);
查找 ISP DNS 缓存——从网络服务商(比如电信)的 DNS 缓存信息中查找(如果没有则往下);
经由以上方式都没找到对应 IP 的话,就会向根域名服务器查找目标 URL 对应的 IP,根域名服务器会向下级服务器转达请求,层层下发,直到找到对应的 IP 为止。
3.浏览器根据 IP 地址与服务器建立联系;
第 2 步中,浏览器通过 IP 寻址找到了对应的服务器,浏览器就将用户发起的 HTTP 请求发送给服务器。服务器开始处理用户请求:
每台服务器上都会安装处理请求的应用——Web Server;
常见的 Web Server 产品有:Apache 、Nginx 、IIS 和 lighttpd 等;
Web Server 可以理解为一个管理者,它不做具体的请求处理,而是会结合配置文件,把不同用户发来的请求委托给服务器上专门处理相应请求的程序(服务器上的相应程序开始处理请求的这一部分,通俗说就是实际后台处理的工作):
后台开发现在有很多框架,但大部分都是按照 MVC(Model View Controller)设计模式搭建的,它将服务器上的应用程序分成 3 个核心部件且分别处理自己的任务,实现输入、处理、输出的分离:
4.浏览器与服务器通信:浏览器请求,服务器处理请求并呈现页面。
在上边的第 3 步中,服务器返回了 HTML 字符串给浏览器,此时,浏览器将会对其进行解析、渲染并最终绘制网页:
(1)加载:
浏览器对一个 HTML 页面的加载顺序是从上而下的;
浏览器在加载的过程中,同时进行解析、渲染处理;
在这个过程中,遇到 link 标签、image 标签、script 标签时,浏览器会再次向服务器发送请求以获取相应的 CSS 文件、图片资源、JS 文件,并执行 JS 代码,同步进行加载、解析。
(2)解析、渲染
解析的过程,其实就是生成“树”(Document Object Model 文档对象模型);
DOM 树是由 DOM 元素及属性节点组成,并且加上 CSS 解析的样式对象和 JS 解析后的动作实现;
渲染:就是将 DOM 树进行可视化表示。
(3) 绘制网页
浏览器通过渲染,将 DOM 树可视化,得到渲染树;
构建渲染树使页面以正确的顺序绘制出来,浏览器遵循一定的渲染规则,实现网站页面的绘制,并最终完成页面的展示。
2. 一次完整的 HTTP 事务是怎么一个过程?
a. 域名解析
b. 发起TCP的3次握手
c. 建立TCP连接后发起http请求
d. 服务器端响应http请求,浏览器得到html代码
e. 浏览器解析html代码,并请求html代码中的资源
f. 浏览器对页面进行渲染呈现给用户
3. 浏览器是如何渲染页面的?
a.处理HTML标记并构建DOM树
b.处理CSS标记并构建CSSOM树
c.将DOM与CSSOM合并成一个渲染树
d.根据渲染树来布局,计算每个节点的布局信息
e.将各个节点绘制到屏幕上
4. 浏览器的内核有哪些?分别有什么代表的浏览器?
a.Trident 内核:IE,搜狗高速浏览器等
b.Gecko 内核:Mozilla Firefox(火狐浏览器),Netscape6及以上版本
c.Webkit 内核:Safari 、曾经的 Chrome
d.Presto 内核:Opera 7到Opera12.17(欧朋浏览器)之间的版本采用的内核
e.Blink 内核:现在 Chrome 内核是 Blink,Opera现已改用Google Chrome的Blink内核
5. 刷新页面,JS 请求一般会有哪些地方有缓存处理?
a.DNS缓存:短时间内多次访问某个网站,在限定时间内,不用多次访问DNS服务器。
b.CDN缓存:内容分发网络(人们可以在就近的代售点取火车票了,不用非得到火车站去排队)
c.浏览器缓存:浏览器在用户磁盘上,对最新请求过的文档进行了存储。
d.服务器缓存:将需要频繁访问的Web页面和对象保存在离用户更近的系统中,当再次访问这些对象的时候加快了速度。
2、HTML相关
2.1基础
1. DOCTYPE 有什么作用?怎么写?
DOCTYPE声明中指出阅读程序应该用什么规则来解释文档中的标记。在Web文档的情况下,阅读程序通常是浏览器或者校验器这样的一个程序,规则是W3C所发布的一个文档类型定义
DTD
中包含的规则。制作一个符合标准的网页,DOCTYPE声明是是不可缺少的,它在Web设计中用来说明你用的XHTML或者HTML是什么版本,如果不做DOCTYPE声明或声明不正确的情况下,将有可能导致你的标识与CSS失效,从而令你网页的布局变乱,造成网页在浏览器中不能正常的显示。我们还可以通过W3C提供的验证工具来检查页面的内容是否符合在DOCTYPE中声明的标准。
如果不声明doctype会发生什么?如何解决?
声明文档的解析类型(document.compatMode),避免浏览器的怪异模式。这个属性会被浏览器识别并使用,但是如果你的页面没有DOCTYPE的声明,那么compatMode默认就是BackCompat,这也就是怪异的开始
浏览器按照自己的方式解析渲染页面,那么,在不同的浏览器就会显示不同的样式。如果你的页面添加了,那么就等同于开启了标准模式,那么浏览器就得老老实实的按照W3C的标准解析渲染页面,这样一来,你的页面在所有的浏览器里显示的就都是一个样子了。
有没有其他进入怪异模式的方法?除了不写DOCTYPE声明外,最常见的就是在DOCTYPE声明前面出现了这些内容:普通文本、HTML 标签、HTML 注释、XML 声明、IE条件注释。
2. 列出常见的标签,并简单介绍这些标签用在什么场景?
<a> 用于超链接。<a href="">some text</a>
<article> 用于一篇文章。<article>a self-contained article</article>
<aside> 用于页面的侧边栏。<aside>some content</aside>
<blockquote> 用于大段的引用内容。<blockquote>some big texts</blockquote>
<body> 页面上显示的所有内容都被包含在<body></body>里
<br> 用于显示一个换行
<button> 用于显示一个按钮
<code> 用于一包裹一段代码内容
<dd> 用于一个dl列表的某个dt名词的描述
<del> 用于删除一些不需要的文字
<div> 用于包裹住一些其他的标签,制造一个容器
<dl> 用于制作一个名词和对应解释的列表
<dt> 用于一个dl列表的某个dt名词
<em> 用于强调一些文本内容
<figcaption> 用于一张图表的说明文字
<figure> 用于一张图表
<footer> 用于包裹页面的底部内容
<form> 用于制作一个表单
<h1>-<h6> 用于标记标题,从h1到h6重要性依次递减
<head> 用于包裹页面的元数据,如<meta>, <link>, <title>等
<header> 用于包裹页面的头部内容
<hr> 用于制造出一条分隔线
<html> 整个 HTML 文档的根元素,包裹住其他所有的元素
<iframe> 用于嵌入另一个小页面到一个页面中
<img> 用于显示一张图片
<input> 用于显示一个表格输入控件
<label> 用于给一个表格输入控件打上一个标签,说明输入控件的作用
<li> 用于<ul>和<ol>标签,代表一个列表项
<link> 用于链接外部CSS文件
<mark> 用于高亮显示某些文本
<meta> 用于下达一些元数据指令,或者对页面进行说明
<nav> 用于包裹住一个导航条的内容
<ol> 用于制作一个有序列表
<p> 用于显示一个段落
<q> 用于一小段引用文字
<script> 用于一段JavaScript脚本代码,或者引入一个外部JavaScript脚本文件
<section> 用于包裹一部分有逻辑关第的页面内容
<select> 用于制作一个下拉列表选框
<span> 用于包裹住一小段文字,作为一个容器
<strong> 用于着重强调重要的文本内容
<style> 用于给页面元素加上样式
<sub> 用于下标文本
<sup> 用于上标文本
<table> 用于制作一个表格
<tbody> 用于表格里的主体部分
<td> 用于表格里的某一个单元格
<textarea> 用于制作一大块文本输入框
<tfoot> 用于表格里的底部
<th> 用于表格里的表头的单元格
<thead> 用于表格里的表头
<time> 用于页面内容中的时间
<title> 用于显示整个页面的标题(显示在浏览器的tab上)
<tr> 用于标记表格里的一行
<ul> 用于制作一个无序列表
3. 页面出现了乱码,是怎么回事?如何解决?
网页乱码出现通常是因为网页开发者没有按照规范来设置网页编码,浏览器打开这类网页的时候自动按照默认的编码来打开导致的。
<head><metahttp-equiv="Content-Type"content="text/html; charset=utf-8"/><head>
把文件保存成utf-8的编码,仿着上面的位置,在页面加上中间那行代码
4. title 属性和 alt 属性分别有什么作用?
1.alt属性
使用alt属性是为了给那些不能看到你文档中图像的浏览者提供文字说明。这包括那些使用本来就不支持图像显示或者图像显示被关闭的浏览器的用户,视觉障碍的用户和使用屏幕阅读器的用户。替换文字是用来替代图像而不是提供额外说明文字的。alt属性包括替换说明,对于图像和图像热点是必须的。它只能用在img、area和input元素中(包括applet元素)。
2.title属性
title属性为设置该属性的元素提供建议性的信息。使用title属性提供非本质的额外信息。大部分的可视化浏览器在鼠标悬浮在特定元素上时显示title文字为提示信息(tool tip),然而这又由制造商来决定如何渲染title文字。
title属性有一个很好的用途,即为链接添加描述性文字,特别是当连接本身并不是十分清楚的表达了链接的目的。这样就使得访问者知道那些链接将会带他们到什么地方,他们就不会加载一个可能完全不感兴趣的页面。另外一个潜在的应用就是为图像提供额外的说明信息,比如日期或者其他非本质的信息。
title属性可以用在除了base,basefont,head,html,meta,param,script和title之外的所有标签。但是并不是必须的。
5. HTML 的注释怎样写?
<!-- 在此处写注释 -->
在开始标签中有一个惊叹号,但是结束标签中没有。浏览器不会显示注释,但是能够帮助记录您的 HTML 文档。您可以利用注释在 HTML 中放置通知和提醒信息:
6. HTML5 为什么只写 <!DOCTYPE html> ?
HTML5 不基于 SGML,因此不需要对DTD进行引用,但是需要doctype来规范浏览器的行为(让浏览器按照它们应该的方式来运行);而HTML4.01基于SGML,所以需要对DTD进行引用,才能告知浏览器文档所使用的文档类型。
拓展:
SGML是标准通用标记语言
HTML是超文本标记语言,主要是用于规定怎么显示网页
XML是可扩展标记语言是未来网页语言的发展方向,可能会替代HTML,他和HTML都是由SGML延伸转变而来的,你可以理解SGML是最早的版本,但现在已经淘汰不用了
XML和HTML的最大区别就在于 XML的标签是可以自己创建的,数量无限多,而HTML的标签都是固定的而且数量有限。
还有一个是XHTML也是现在基本上所有网页都在用的标记语言,他其实和HTML没什么本质的区别标签都一样,用法也都一样,就是比HTML更严格,比如标签必须都用小写,标签都必须有闭合标签等。
7. data- 属性的作用?
data-为H5新增的为前端开发者提供自定义的属性,这些属性集可以通过对象的dataset属性获取,不支持该属性的浏览器可以通过getAttribute方法获取 :
需要注意的是:data-之后的以连字符分割的多个单词组成的属性,获取的时候使用驼峰风格。 所有主流浏览器都支持 data-* 属性。
8. <img> 的 title 和 alt 有什么区别?
title 可提高图片高可访问性,除了纯装饰图片外都必须设置有意义的值,搜索引擎会重点分析。鼠标滑过时显示的文字提示,用户体验上很重要。当然不必要所有的img标签都加此属性,比方说logo这样比较重要或者说用户会体验到的图片内容建议一定要加此属性。
9. Web 标准以及 W3C 标准是什么?
web标准:web标准
web标准简单来说可以分为结构、表现和行为。其中结构主要是有HTML标签组成。或许通俗点说,在页面body里面我们写入的标签都是为了页面的结构。表现即指css样式表,通过css可以是页面的结构标签更具美感。行为是指页面和用户具有一定的交互,同时页面结构或者表现发生变化,主要是有js、dom组成。
web标准一般是将该三部分独立分开,使其更具有模块化。但一般产生行为时,就会有结构或者表现的变化,也使这三者的界限并不那么清晰。
w3c标准: 点击打开链接
1.对于结构要求:(标签规范可以提高搜索引擎对页面的抓取效率,对SEO很有帮助)
1)标签字母要小写
2)标签要闭合
3)标签不允许随意嵌套
2.对于css和js来说
1)尽量使用外链css样式表和js脚本。是结构、表现和行为分为三块,符合规范。同时提高页面渲染速度,提高用户的体验。
2)样式尽量少用行间样式表,使结构与表现分离,标签的id和class等属性命名要做到见文知义,标签越少,加载越快,用户体验提高,代码维护简单,便于改版
3)不需要变动页面内容,便可提供打印版本而不需要复制内容,提高网站易用性。
10. DOCTYPE 作用?严格模式与混杂模式如何区分?它们有何意义?
Doctype作用是什么?
<!DOCTYPE>声明叫做文件类型定义(DTD),声明的作用为了告诉浏览器该文件的类型。让浏览器解析器知道应该用哪个规范来解析文档。<!DOCTYPE>声明必须在 HTML 文档的第一行,这并不是一个 HTML 标签。
严格模式与混杂模式如何区分?它们有何意义?
严格模式:又称标准模式,是指浏览器按照 W3C 标准解析代码。
混杂模式:又称怪异模式或兼容模式,是指浏览器用自己的方式解析代码。
如何区分:浏览器解析时到底使用严格模式还是混杂模式,与网页中的 DTD 直接相关。
1、如果文档包含严格的 DOCTYPE ,那么它一般以严格模式呈现。(严格 DTD ——严格模式)
2、包含过渡 DTD 和 URI 的 DOCTYPE ,也以严格模式呈现,但有过渡 DTD 而没有 URI (统一资源标识符,就是声明最后的地址)会导致页面以混杂模式呈现。(有 URI 的过渡 DTD ——严格模式;没有 URI 的过渡 DTD ——混杂模式)
3、DOCTYPE 不存在或形式不正确会导致文档以混杂模式呈现。(DTD不存在或者格式不正确——混杂模式)
4、HTML5 没有 DTD ,因此也就没有严格模式与混杂模式的区别,HTML5 有相对宽松的语法,实现时,已经尽可能大的实现了向后兼容。( HTML5 没有严格和混杂之分)
意义:严格模式与混杂模式存在的意义与其来源密切相关,如果说只存在严格模式,那么许多旧网站必然受到影响,如果只存在混杂模式,那么会回到当时浏览器大战时的混乱,每个浏览器都有自己的解析模式
11. HTML 全局属性(Global Attribute)有哪些?
accesskey规定激活元素的快捷键;
class规定元素的一个或多个类名(引用样式表中的类);
contenteditable规定元素内容是否可编辑;
contextmenu规定元素的上下文菜单。上下文菜单在用户点击元素时显示。
data-*用于存储页面或应用程序的私有定制数据。
dir规定元素中内容的文本方向。
draggable规定元素是否可拖动。
dropzone规定在拖动被拖动数据时是否进行复制、移动或链接。
hidden样式上会导致元素不显示,但是不能用这个属性实现样式。
id规定元素的唯一 id。
lang规定元素内容的语言。
spellcheck规定是否对元素进行拼写和语法检查。
style规定元素的CSS行内元素。
tabindex规定元素的tab键次序。
title规定有关元素的额外信息。
translate规定是否应该翻译元素内容。
2.2HTML 元素、属性详解 | HTML
1. meta 有哪些常见的值?
meta元素共有三个可选属性(http-equiv、name和scheme)和一个必选属性(content),content定义与 http-equiv 或 name 属性相关的元信息
可选属性
属性:http-equiv 值:content-type / expire / refresh / set-cookie 描述:把content属性关联到HTTP头部
属性:name 值:author / description / keywords / generator / revised / others 描述:把 content 属性关联到一个名称
属性:scheme 值:some_text 描述:定义用于翻译 content 属性值的格式
必选属性
属性:content 值:some_text 描述:定义与 http-equiv 或 name 属性相关的元信息
2. meta viewport 是做什么用的,怎么写?
在每个html页面的header部分常常会看见一个meta标签. 这个标签中最常写的就是下面的内容:
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
这个标签内的内容表示啥意思呢?
name为viewport表示供移动设备使用. content定义了viewport的属性.
width表示移动设设备下显示的宽度为设备宽度(device-width)
height表示移动设设备下显示的宽度为设备宽度.
user-scalable表示用户缩放能力, no表示不允许.
initial-scale表示设备与视口的缩放比率
maximum和minimum分别表示缩放的最大最小值, 要注意的是, maximum必须必minimum大.
上面的meta标签就是告诉浏览器, 不要在移动端显示的时候缩放.
meta viewport
meta viewport是专为移动设备下显示所设计的.只有检测到在移动设备上使用包含meta的文档时, meta标签才会起作用.
在meta标签中, 当name为viewpor时, 有下面的约定:
width 一个正整数或者字符串 device-width 以pixels(像素)为单位, 定义viewport(视口)的宽度。
height 一个正整数或者字符串 device-height 以pixels(像素)为单位, 定义viewport(视口)的高度。
initial-scale 一个0.0 到10.0之间的正数 定义设备宽度(纵向模式下的设备宽度或横向模式下的设备高度)与视口大小之间的缩放比率。
maximum-scale 一个0.0 到10.0之间的正数 定义缩放的最大值;它必须大于或等于minimum-scale的值,不然会导致不确定的行为发生。
minimum-scale 一个0.0 到10.0之间的正数 定义缩放的最小值;它必须小于或等于maximum-scale的值,不然会导致不确定的行为发生。
user-scalable 一个布尔值(yes 或者no) 如果设置为 no,用户将不能放大或缩小网页。默认值为 yes。
3. 如何在 HTML 页面上展示 <div></div> 这几个字符?
如果要在网页中显示一些特殊的字符,就要用转义符号
如 :标签的大于和小于号需要进行转义
< 在浏览器中会显示为<
> 在浏览器中会显示为>
如:<div><div>会显示为<div></div>
4. 你是如何理解 HTML 语义化的?
什么是HTML语义化
首先标签语义化是指HTML,不是CSS, 语义化标签只是HTML,CSS不存在语义化。HTML是标签,CSS是属性。
在最初html里标签的语义,我们看到table,就会知道这是列表,看到p,就知道这是段落,看到img知道是图片,看到input就知道这是一个表单,h1~h6是标题。 机器和人类相比笨多了,但是只要我们设定好程序,上面的标签的意思机器也能读懂。
但是也有些是无语义化的如div—division并不能表示div标签里面内容的属性和表现样式
HTML 标签语义化是让大家直观的通过标签(markup)和属性(attribute)来知道其用途和作用。
去掉样式,看网页结构是否组织良好有序,是否仍然有很好的可读性。
1.尽可能少的使用无语义的标签div和span;
2.在语义不明显时,既可以使用div或者p时,尽量用p, 因为p在默认情况下有上下间距,对兼容特殊终端有利;
3.不要使用纯样式标签,如:b、font、u等,改用css设置。
4.需要强调的文本,可以包含在strong或者em标签中(浏览器预设样式,能用CSS指定就不用他们),strong默认样式是加粗(不要用b),em是斜体(不用i);
5.使用表格时,标题要用caption,表头用thead,主体部分用tbody包围,尾部用tfoot包围。表头和一般单元格要区分开,表头用th,单元格用td;
6.每个input标签对应的说明文本都需要使用label标签,并且通过为input设置id属性,在lable标签中设置for=someld来让说明文本和相对应的input关联起来
1.清晰的页面结构。去掉或样式丢失的时候,也能让页面呈现清晰的结构,增强页面的可读性。
2.支持更多的设备。屏幕阅读器会完全根据你的标记来“读”你的网页。更好的支持浏览器的阅读模式等。
3.有利于SEO(搜索引擎优化)。和搜索引擎建立良好沟通,有助于爬虫抓取更多的有效信息,搜索引擎的爬虫也依赖于标记来确定上下文和各个关键字的权重。
4.便于团队开发和维护。在团队中大家都遵循同一个标准,可以减少很多差异化的东西,方便开发和维护,提高开发效率,甚至实现模块化开发。
5.方便其他设备解析(如屏幕阅读器、盲人阅读器、移动设备)以意义的方式来渲染网页;
拓展:HTML5新增了哪些语义化标签?
header元素代表“网页“和”section”的页眉。
footer元素代表“网页”或“section”的页脚,通常含有该页面的一些基本信息
hgroup元素代表“网页”或“section”的标题,当元素有多个层级时,该元素可以将h1到h6元素放在其内,譬如文章的主标题和副标题的组合
nav元素代表页面的导航链接区域。用于定义页面的主要导航部分。
aside元素被包含在article元素中作为主要内容的附属信息部分,其中的内容可以是与当前文章有关的相关资料、标签、名词解释等
article元素最容易跟section和div容易混淆,其实article代表一个在文档,页面或者网站中自成一体的内容,其目的是为了让开发者独立开发或重用。
video,audio等
5. 前端需要注意哪些 SEO?
1.合理的title、description、keywords:搜索对着三项的权重逐个减小,title值强调重点即可,重要关键词出现不要超过2次,而且要靠前,不同页面title要有所不同;description把页面内容高度概括,长度合适,不可过分堆砌关键词,不同页面description有所不同;keywords列举出重要关键词即可
2.语义化的HTML代码,符合W3C规范:语义化代码让搜索引擎容易理解网页
3.重要内容HTML代码放在最前:搜索引擎抓取HTML顺序是从上到下,有的搜索引擎对抓取长度有限制,保证重要内容一定会被抓取
4.重要内容不要用js输出:爬虫不会执行js获取内容
5.少用iframe:搜索引擎不会抓取iframe中的内容
6.非装饰性图片必须加alt
7.提高网站速度:网站速度是搜索引擎排序的一个重要指标
2.3HTML 表单详解 | HTML
1. POST 和 GET 方式提交数据有什么区别?
总结:
GET的优点:
1.执行效率比POST高。
2.可以通过url传递数据,可用来查找数据。
GET的缺点:
1.安全性很低,因为上传的数据都会显示在url上,所以一般用在上传无关紧要的数据上。
2.上传的数据量较小,一般不能超过2048个字符,这也是因为url的长度而被限制的。
POST优点:
1.安全性高,但是也不是很高,如果想要高安全性的话就用https传输协议。
2.上传的数据量比GET大得多。“理论上讲,POST是没有大小限制的,HTTP协议规范也没有进行大小限制
POST缺点:
1.执行效率比GET低,因为多了向服务器请求这一过程,但是现在的计算机都很强大,这些几乎可以忽略不计,所以建议一般都使用POST方式。
2.不可以通过url传递数据,有时候可能会不方便.
其他:
两种 HTTP 请求方法:GET 和 POST
在客户机和服务器之间进行请求-响应时,两种最常被用到的方法是:GET 和 POST。
GET- 从指定的资源请求数据。
POST- 向指定的资源提交要被处理的数据
其他 HTTP 请求方法:
2. 在 input 里,name 有什么作用?
1.作为可与服务器交互数据的HTML元素的服务器端的标示,比如input、select、textarea、和button等。我们可以在服务器端根据其Name通过Request.Params取得元素提交的值。
2. HTML元素Input type='radio'分组,我们知道radio button控件在同一个分组类,check操作是mutex的,同一时间只能选中一个radio,这个分组就是根据相同的Name属性来实现的。
3.建立页面中的锚点,我们知道<a href="URL">link</a>是获得一个页面超级链接,如果不用href属性,而改用Name,如:<a name="PageBottom"></a>,我们就获得了一个页面锚点。
4.作为对象的Identity,如Applet、Object、Embed等元素。比如在Applet对象实例中,我们将使用其Name来引用该对象。
5.在IMG元素和MAP元素之间关联的时候,如果要定义IMG的热点区域,需要使用其属性usemap,使usemap="#name"(被关联的MAP元素的Name)。
6.某些特定元素的属性,如attribute,meta和param。例如:
为Object定义参数<PARAM NAME ="appletParameter" VALUE = "value">或Meta中<META NAME = "Author" CONTENT = "Dave Raggett">。
3. label 有什么作用?如何使用?
Label 中有两个属性是非常有用的,一个是FOR、另外一个就是ACCESSKEY了。
FOR属性
功能:表示Label标签要绑定的HTML元素,你点击这个标签的时候,所绑定的元素将获取焦点。
用法:姓名
ACCESSKEY属性:
功能:表示访问Label标签所绑定的元素的热键,当您按下热键,所绑定的元素将获取焦点。
用法:姓名
局限性:accessKey属性所设置的快捷键不能与浏览器的快捷键冲突,否则将优先激活浏览器的快捷键。
4. radio 如何分组?
将name设置相同值
5. placeholder 属性有什么作用?
placeholder 属性提供可描述输入字段预期值的提示信息(hint)。
该提示会在输入字段为空时显示,并会在字段获得焦点时消失。
注释:placeholder 属性适用于以下的
类型:text, search, url, telephone, email 以及 password
6. type=hidden 隐藏域有什么作用?举例说明。
1、隐藏域在页面中对于用户是不可见的,在表单中插入隐藏域的目的在于收集或发送信息,以利于被处理表单的程序所使用。浏览者单击发送按钮发送表单的时候,隐藏域的信息也被一起发送到服务器。
2、有些时候我们要给用户一信息,让他在提交表单时提交上来以确定用户身份,如sessionkey,等等.当然这些东西也能用cookie实现,但使用隐藏域就简单的多了.而且不会有浏览器不支持,用户禁用cookie的烦恼。
3、有些时候一个form里有多个提交按钮,怎样使程序能够分清楚到底用户是按那一个按钮提交上来的呢?我们就可以写一个隐藏域,然后在每一个按钮处加上 onclick="document.form.command.value="xx""然后我们接到数据后先检查command的值就会知道用户是按的那个按钮提交上来的。
4、有时候一个网页中有多个form,我们知道多个form是不能同时提交的,但有时这些form确实相互作用,我们就可以在form中添加隐藏域来使它们联系起来。
5、javascript不支持全局变量,但有时我们必须用全局变量,我们就可以把值先存在隐藏域里,它的值就不会丢失了。
6、还有个例子,比如按一个按钮弹出四个小窗口,当点击其中的一个小窗口时其他三个自动关闭.可是IE不支持小窗口相互调用,所以只有在父窗口写个隐藏域,当小窗口看到那个隐藏域的值是close时就自己关掉。
如:
1、<input type=hidden name=coun value=<%=cc%>>
这里的隐藏域名为coun,值为<%=cc%>,假设前面cc=100的话,即值为100;
2、递交表单<form action=xx.asp>到新页面xx.asp;
3、在xx.asp页中,使用request.write request.form("coun"),则在页面中显示的值就是100。
7. CSRF 攻击是什么?如何防范?
CSRF(Cross-site request forgery)也被称为 one-click attack或者 session riding,中文全称是叫跨站请求伪造。一般来说,攻击者通过伪造用户的浏览器的请求,向访问一个用户自己曾经认证访问过的网站发送出去,使目标网站接收并误以为是用户的真实操作而去执行命令。常用于盗取账号、转账、发送虚假消息等。攻击者利用网站对请求的验证漏洞而实现这样的攻击行为,网站能够确认请求来源于用户的浏览器,却不能验证请求是否源于用户的真实意愿下的操作行为。
如何防范?
1.验证 HTTP Referer 字段
HTTP头中的Referer字段记录了该 HTTP 请求的来源地址。在通常情况下,访问一个安全受限页面的请求来自于同一个网站,而如果黑客要对其实施 CSRF
攻击,他一般只能在他自己的网站构造请求。因此,可以通过验证Referer值来防御CSRF 攻击。
2.使用验证码
关键操作页面加上验证码,后台收到请求后通过判断验证码可以防御CSRF。但这种方法对用户不太友好。
3.在请求地址中添加token并验证
CSRF 攻击之所以能够成功,是因为黑客可以完全伪造用户的请求,该请求中所有的用户验证信息都是存在于cookie中,因此黑客可以在不知道这些验证信息的情况下直接利用用户自己的cookie 来通过安全验证。要抵御 CSRF,关键在于在请求中放入黑客所不能伪造的信息,并且该信息不存在于 cookie 之中。可以在 HTTP 请求中以参数的形式加入一个随机产生的 token,并在服务器端建立一个拦截器来验证这个 token,如果请求中没有token或者 token 内容不正确,则认为可能是 CSRF 攻击而拒绝该请求。这种方法要比检查 Referer 要安全一些,token 可以在用户登陆后产生并放于session之中,然后在每次请求时把token 从 session 中拿出,与请求中的 token 进行比对,但这种方法的难点在于如何把 token 以参数的形式加入请求。
对于 GET 请求,token 将附在请求地址之后,这样 URL 就变成http://url?csrftoken=tokenvalue。
而对于 POST 请求来说,要在 form 的最后加上 ,这样就把token以参数的形式加入请求了。
4.在HTTP 头中自定义属性并验证
这种方法也是使用 token 并进行验证,和上一种方法不同的是,这里并不是把 token 以参数的形式置于 HTTP 请求之中,而是把它放到 HTTP 头中自定义的属性里。通过 XMLHttpRequest 这个类,可以一次性给所有该类请求加上 csrftoken 这个 HTTP 头属性,并把 token 值放入其中。这样解决了上种方法在请求中加入 token 的不便,同时,通过 XMLHttpRequest 请求的地址不会被记录到浏览器的地址栏,也不用担心 token 会透过 Referer 泄露到其他网站中去。
AngularJS提供的CSRF方案
AngularJS提供了对CSRF防御的支持,当cookie中存在名为XSRF-TOKEN的cookie时,会在POST/PUT/DELETE请求中带上名为X-XSRF-TOKEN的http header。(For Angular, it expects the cookie named XSRF-TOKEN and will do POST/PUT/DELETE requests with X-XSRF-TOKEN header.)
因此很容易就能采用上面的在HTTP头中带上token验证的方案来防御CSFR。
如果要修改默认的名称,可以设置下面两项:
$httpProvider.defaults.xsrfCookieName = 'csrftoken';
$httpProvider.defaults.xsrfHeaderName = 'X-CSRFToken';
参考:http://blog.csdn.net/prstaxy/article/details/68940360
8. 网页验证码是干嘛的?是为了解决什么安全问题?
区分用户是计算机还是人的公共全自动程序。可以防止恶意破解密码、刷票、论坛灌水;
有效防止黑客对某一个特定注册用户用特定程序暴力破解方式进行不断的登陆尝试。
9. 常见 Web 安全及防护原理?
1.sql注入原理
就是通过把sql命令插入到web表单递交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令。
防护,总的来说有以下几点:
1、永远不要信任用户的输入,要对用户的输入进行校验,可以通过正则表达式,或限制长度,对单引号双“--”进行转换等。
2、永远不要使用动态拼装sql,可以使用参数化的sql或者直接使用存储过程进行数据查询存取。
3、永远不要使用管理员权限进行数据库连接,为每个应用使用单独的权限有限的数据库连接。
4、不要把机密信息明文存放,请加密或者hash掉密码和敏感的信息。
2. XSS原理及防范
XSS(cross-sitescripting)攻击指的是攻击者往Web页面里插入恶意html标签或者javascript代码。比如:攻击者在qq中发送一个看似安全的链接,骗取用户点击之后,窃取cookie中的用户私密信息;或者攻击者在论坛中加一个恶意表单,当用户提交表单的时候,却把信息传送到攻击者的服务器中,而不是用户原本以为信任的站点。
3.XSS防范方法
首先代码里对用户输入的地方和变量都需要仔细检查长度和对“<”,">" ,";"," ‘ "等字符做过滤;其次任何内容写到页面之前都必须加以encode,避免不小心把html tag弄出来。至少可以堵住超过一半的XSS攻击。
首先,避免直接在cookie中泄漏用户隐私,例如email、密码等等。其次,通过使用cookie和系统ip绑定来降低cookie泄漏后的危险。这样攻击者得到的cookie没有实际价值,不可能拿来重放。
如果网站不需要在浏览器端对cookie进行操作,可以在set-cookie末尾加上HttpOnly来防止JavaScript代码直接获取cookie 。
尽量采用post而非get提交表单
4.XSS与CSRF有什么区别吗?
XSS是获取信息,不需要提前知道其他用户页面的代码和数据包。CSRF是代替用户完成指定的动作,需要知道其他用户页面的代码和数据包。
要完成一次CSRF攻击,受害者必须依次完成两个步骤:
登录受信任网站A,并在本地生成cookie。
在不登出A的情况下,访问危险网站B。
5.CSRF的防范
服务器端的CSRF方式方法很多样,但总的思想都是一致的,就是在客户端页面增加伪随机数。
10、前后端交互
1. HTTP 状态码知道哪些?
100 Continue 继续,一般在发送post请求时,已发送了http header之后服务端将返回此信息,表示确认,之后发送具体参数信息
200 OK 正常返回信息
201 Created 请求成功并且服务器创建了新的资源
202 Accepted 服务器已接受请求,但尚未处理
301 Moved Permanently 请求的网页已永久移动到新位置。
302 Found 临时性重定向。
303 See Other 临时性重定向,且总是使用 GET 请求新的 URI。
304 Not Modified 自从上次请求后,请求的网页未修改过。
400 Bad Request 服务器无法理解请求的格式,客户端不应当尝试再次使用相同的内容发起请求。
401 Unauthorized 请求未授权。
403 Forbidden 禁止访问。
404 Not Found 找不到如何与 URI 相匹配的资源。
500 Internal Server Error 最常见的服务器端错误。
503 Service Unavailable 服务器端暂时无法处理请求(可能是过载或维护)。
2. AJAX 是什么?有什么作用?
ajax即asynchronous javascript and xml(异步javascript和xml),它并不是一门新技术,而是由javascript css dom(文档对象模型),xmlhttprequest混合实现的。
作用:通过AjAx与服务器进行数据交换,AjAx可以使用网页实现布局更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。
3. AJAX 原理?
Ajax相当于在用户和服务器之间加了—个中间层,使用户操作与服务器响应异步化。并不是所有的用户请求都提交给服务器,像—些数据验证和数据处理等都交给Ajax引擎自己来做, 只有确定需要从服务器读取新数据时再由Ajax引擎代为向服务器提交请求。
Ajax的原理简单来说通过XmlHttpRequest对象来向服务器发送异步请求,从服务器获得数据,然后用javascript来操作DOM而更新页面。这其中最关键的一步就是从服务器获得请求数据。要清楚这个过程和原理,我们必须对 XMLHttpRequest有所了解。
4. HTTPS 是如何实现加密的?
HTTP是属于应用层的协议,它是基于TCP/IP的,所以它只是规定一些要传输的内容,以及头部信息,然后通过TCP协议进行传输,依靠IP协议进行寻址,通过一幅最简单的图来描述
客户端发出请求,服务端进行响应,就是这么简单。在整个过程中,没有任何加密的东西,所以它是不安全的,中间人可以进行拦截,获取传输和响应的数据,造成数据泄露。
加个密呢?
因为上图中数据是明文传输的,我们能想到最简单的提高安全性的方法就是在传输前对数据进行加密,如下图:
这种加密方式叫做:对称加密。
加密和解密用同一个秘钥的加密方式叫做对称加密
好了,我们对数据进行加密了,问题解决了吗?
多个客户端怎么办?
这是一个客户端,但是在WWW上,是成千上万的客户端,情况会怎样呢?
为所有的客户端都应用同一个秘钥A,这种方式很显然是不合理的,破解了一个用户,所有的用户信息都会被盗取。
想一想,是不是还有别的办法呢?
相信大家都可以想到,如果对每一个客户端都用不同的秘钥进行传输是不是就解决这个问题了:
对称加密秘钥如何传输?
我们对每个客户端应用不同的对称加密秘钥,那么这个秘钥客户端或者服务端是如何知道的呢,只能是在一端生成一个秘钥,然后通过HTTP传输给另一端:
那么这个传输秘钥的过程,又如何保证加密?如果被中间人拦截,秘钥也会被获取。也许你会说,对秘钥再进行加密,那又如何保证对秘钥加密的过程,是加密的呢?
好像我们走入了while(1),出不来了。
非对称加密
在对称加密的路上走不通了,我们换个思路,还有一种加密方式叫非对称加密,比如RSA。
非对称加密会有一对秘钥:公钥和私钥。
公钥加密的内容,只有私钥可以解开,私钥加密的内容,所有的公钥都可以解开(当然是指和秘钥是一对的公钥)。
私钥只保存在服务器端,公钥可以发送给所有的客户端。
在传输公钥的过程中,肯定也会有被中间人获取的风险,但在目前的情况下,至少可以保证客户端通过公钥加密的内容,中间人是无法破解的,因为私钥只保存在服务器端,只有私钥可以破解公钥加密的内容。
现在我们还存在一个问题,如果公钥被中间人拿到篡改呢:
MITM:Man-in-the-MiddleAttack
客户端拿到的公钥是假的,如何解决这个问题?
第三方认证
公钥被掉包,是因为客户端无法分辨传回公钥的到底是中间人,还是服务器,这也是密码学中的身份验证问题。
在HTTPS中,使用证书 + 数字签名来解决这个问题。
这里假设加密方式是MD5,将网站的信息加密后通过第三方机构的私钥再次进行加密,生成数字签名。
数字证书 = 网站信息 + 数字签名
假如中间人拦截后把服务器的公钥替换为自己的公钥,因为数字签名的存在,会导致客户端验证签名不匹配,这样就防止了中间人替换公钥的问题。
浏览器安装后会内置一些权威第三方认证机构的公钥,比如VeriSign、Symantec以及GlobalSign等等,验证签名的时候直接就从本地拿到相应第三方机构的公钥,对私钥加密后的数字签名进行解密得到真正的签名,然后客户端利用签名生成规则进行签名生成,看两个签名是否匹配,如果匹配认证通过,不匹配则获取证书失败。
为什么要有签名?
第三方认证机构是一个开放的平台,我们可以去申请,中间人也可以去申请呀:
如果没有签名,只对网站信息进行第三方机构私钥加密的话,会存在下面的问题:
因为没有认证,所以中间人也向第三方认证机构进行申请,然后拦截后把所有的信息都替换成自己的,客户端仍然可以解密,并且无法判断这是服务器的还是中间人的,最后造成数据泄露。
对称加密
在安全的拿到服务器的公钥之后,客户端会随机生成一个对称秘钥,使用服务器公钥加密,传输给服务端,此后,相关的Application Data就通过这个随机生成的对称秘钥进行加密/解密,服务器也通过该对称秘钥进行解密/加密:
整体流程图
HTTPS = HTTP + TLS/SSL
HTTPS中具体的内容还有很多,可以通过下图做一个参考:
总结
HTTPS就是使用SSL/TLS协议进行加密传输,让客户端拿到服务器的公钥,然后客户端随机生成一个对称加密的秘钥,使用公钥加密,传输给服务端,后续的所有信息都通过该对称秘钥进行加密解密,完成整个HTTPS的流程。
5. HTTP 和 HTTPS 的区别?
HTTP协议传输的数据都是未加密的,也就是明文的,因此使用HTTP协议传输隐私信息非常不安全,为了保证这些隐私数据能加密传输,于是网景公司设计了SSL(Secure Sockets Layer)协议用于对HTTP协议传输的数据进行加密,从而就诞生了HTTPS。简单来说,HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,要比http协议安全。
HTTPS和HTTP的区别主要如下:
1、https协议需要到ca申请证书,一般免费证书较少,因而需要一定费用。
2、http是超文本传输协议,信息是明文传输,https则是具有安全性的ssl加密传输协议。
3、http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。
4、http的连接很简单,是无状态的;HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比http协议安全。
6. 如何实现页面每次打开时清除本页缓存?
(1) 用HTML标签设置HTTP头信息
<HEAD>
<META HTTP-EQUIV="Pragma" CONTENT="no-cache">
<META HTTP-EQUIV="Cache-Control" CONTENT="no-cache">
<META HTTP-EQUIV="Expires" CONTENT="0">
</HEAD>
说明:HTTP头信息“Expires”和“Cache-Control”为应用程序服务器提供了一个控制浏览器和代理服务器上缓存的机制。HTTP头信息Expires告诉代理服务器它的缓存页面何时将过期。HTTP1.1规范中新定义的头信息Cache-Control可以通知浏览器不缓存任何页面。当点击后退按钮时,浏览器重新访问服务器已获取页面。如下是使用Cache-Control的基本方法:
1) no-cache:强制缓存从服务器上获取新的页面
2) no-store: 在任何环境下缓存不保存任何页面
HTTP1.0规范中的Pragma:no-cache等同于HTTP1.1规范中的Cache-Control:no-cache,同样可以包含在头信息中。
(2) 在需要打开的url后面增加一个随机的参数:
增加参数前:url=test/test.jsp
增加参数后:url=test/test.jsp?ranparam=random()
说明:因为每次请求的url后面的参数不一样,相当于请求的是不同的页面,用这样的方法来清除缓存
7. 把 GET 和 POST 类型的 AJAX 的用法手写一遍?
// GET
var xhr = new XMLHttpRequest()
xhr.open('GET','/weather.php?username = jirengu&password=123567',true)
xhr.send()
xhr.addEventListener('load',function(){
if(xhr.status > 200 || xhr.status < 300 || xhr.status ===304){
var data = xhr.responseText()
console.log(data);
}else{
console.log('error');
}
})
// POST
var xhr = new XMLHttpRequest()
xhr.open('POST','/login',true)
xhr.onload = function(){
if(xhr.readyState ===4 && xhr.status ===200){
var data = xhr.responseText()
console.log(data);
}else{
console.log('error');
}
}
8. 封装一个 AJAX 函数?
js页面:
function ajax(url,funSucc,funFaild){
//1、创建Ajax对象
var oAjax=null;
if(window.XMLHttpRequest){
oAjax=new XMLHttpRequest();
}else{
oAjax=new ActiveXObject("Microsoft.XMLHTTP");
}
//alert(oAjax);
//alert(oAjax.readyState);
//2、连接服务器
oAjax.open('GET',url,true);//open(方式,url读哪个文件,是否异步)
//alert(oAjax.readyState);
//3、发送请求
oAjax.send();
//4、接收返回值
oAjax.onreadystatechange=function(){//onreadystatechange客户端与服务器通信(提供与文档或元素的加载状态有关的信息)的信息
//oAjax.readyState等于0;表示对象存在但尚未初始化。(还没有调用open()方法)
//oAjax.readyState等于1;表示对象正在加载数据。(已调用send()方法,正在发送请求)
//oAjax.readyState等于2;表示对象加载数据完成。(send()方法完成,已收到全部响应内容)
//oAjax.readyState等于3;可以操作对象了,但还没有完全加载(正在解析响应内容)
//oAjax.readyState等于4;表示对象已经加载完毕。(响应内容解析完成,可以在客户端调用了)
//alert(oAjax.readyState);
if(oAjax.readyState==4){//oAjax.readyState等于4;表示完成,但不表示请求成功
//alert(oAjax.status);
//oAjax.status等于200,表示请求成功;
//oAjax.status等于400多,表示客户端错误;
//oAjax.status等于500多,表示服务器错误;
if(oAjax.status==200){
//alert("成功:"+oAjax.responseText);//responseText表示异步加载的数据
funSucc(oAjax.responseText);
}else{
//alert("失败");
if(funFaild){
funFaild();
}
}
}
}
}
在html页面:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>无标题文档</title>
<script src="ajax.js"></script>
<script>
ajax('abc.txt',function(str){
alert(str);
},function(){
alert("失败了");
});
</script>
</head>
<body>
</body>
</html>
9. 什么是同源策略?
同源策略 是由NetScape提出的一个著名的安全策略。所谓的同源,指的是协议,域名,端口相同。浏览器处于安全方面的考虑,只允许本域名下的接口交互,不同源的客户端脚本,在没有明确授权的情况下,不能读写对方的资源
10. 什么是跨域?列举跨域有几种实现形式?
跨域指的是跨过同源策略,实现不同域之间进行数据交互的过程叫跨域。跨域的实现形式主要有JSONP方法、CORS方法、降域和postMessage等。
实现形式
1.JSONP:依托在html下的script可以加载任意域 下数据的特点,将script的src属性设置成欲请求的数据地址,先通过script去加载对应数据并将其作为js在当前页面运行,就实现了跨域操作,然而,对于某些json格式数据之间作为js执行时根本无法将这些数据进行完美解析渲染,所以可以通过在请求的url末尾上加个回调函数,并和后端进行约定好返回数据格式,将返回数据(如json数据)构造成能够作为js直接执行的格式,就实现了跨域同事前后端的良好交互,如下面例子:
var http = require('http')
var fs = require('fs')
var path = require('path')
var url = require('url')
http.creatServer(function(req,res){
var pathObj = url.parse(req,url,true)
switch(pathObj.pathname){
case'getNews':pathObj
var news =[
"第11日前瞻:中国冲击4金 博尔特再战200米羽球",
"正直播柴飚/洪炜出战 男双力争会师决赛",
"女排将死磕巴西!郎平安排男陪练模仿对方核心"
]
res.setHeader('Content-Type','text/json';charset=utf-8)
if(pathObj.query.callback){
res.end(pathObj.query.callback)+'(' + JSON.stringify(news) +')'
}else{
res.end(JSON.stringify(news))
}
break;
default:
fs.readFile(path.join(__dirname,pathObj.pathname),function(e,data){
if(e){
res.writeHead( 404,'not found')
res.end('<h1>404 not found</h1>')
}else{
res.end(data)
}
})
}
}).listen(8080)
<!DOCTYPE html>
<html>
<body>
<div class="container">
<ul class="news">
</ul>
<button class="show">show news</button>
</div>
<script>
$('.show').addEventListener('click', function(){
var script = document.createElement('script');
script.src = 'http://127.0.0.1:8080/getNews?callback=appendHtml';
document.head.appendChild(script);
document.head.removeChild(script);
})
function appendHtml(news){
var html = '';
for( var i=0; i<news.length; i++){
html += '<li>' + news[i] + '</li>';
}
console.log(html);
$('.news').innerHTML = html;
}
function $(id){
return document.querySelector(id);
}
</script>
</html>
2.CORS :全称是跨域资源共享(Cross-Origin Resource Sharing),是一种 ajax 跨域请求资源的方式,支持现代浏览器,IE支持10以上。 实现方式很简单,当你使用 XMLHttpRequest 发送请求时,浏览器发现该请求不符合同源策略,会给该请求加一个请求头:Origin,后台进行一系列处理,如果确定接受请求则在返回结果中加入一个响应头:Access-Control-Allow-Origin; 浏览器判断该相应头中是否包含 Origin 的值,如果有则浏览器会处理响应,我们就可以拿到响应数据,如果不包含浏览器直接驳回,这时我们无法拿到响应数据。所以 CORS 的表象是让你觉得它与同源的 ajax 请求没啥区别,代码完全一样。
var http = require('http')
var fs = require('fs')
var path = require('path')
var url = require('url')
http.createServer(function(req, res){
var pathObj = url.parse(req.url, true)
switch (pathObj.pathname) {
case '/getNews':
var news = [
"第11日前瞻:中国冲击4金 博尔特再战200米羽球",
"正直播柴飚/洪炜出战 男双力争会师决赛",
"女排将死磕巴西!郎平安排男陪练模仿对方核心"
]
res.setHeader('Access-Control-Allow-Origin','http://localhost:8080')
//res.setHeader('Access-Control-Allow-Origin','*')
res.end(JSON.stringify(news))
break;
default:
fs.readFile(path.join(__dirname, pathObj.pathname), function(e, data){
if(e){
res.writeHead(404, 'not found')
res.end('<h1>404 Not Found</h1>')
}else{
res.end(data)
}
})
}
}).listen(8080)
index.html
<!DOCTYPE html>
<html>
<body>
<div class="container">
<ul class="news">
</ul>
<button class="show">show news</button>
</div>
<script>
$('.show').addEventListener('click', function(){
var xhr = new XMLHttpRequest()
xhr.open('GET', 'http://127.0.0.1:8080/getNews', true)
xhr.send()
xhr.onload = function(){
appendHtml(JSON.parse(xhr.responseText))
}
})
function appendHtml(news){
var html = ''
for( var i=0; i<news.length; i++){
html += '<li>' + news[i] + '</li>'
}
$('.news').innerHTML = html
}
function $(selector){
return document.querySelector(selector)
}
</script>
</html>
11. JSONP 的原理是什么?
jsonp,即json+padding(创建一个回调函数,然后在远程服务上调用这个函数并且将JSON 数据形式作为参数传递,完成回调。将JSON数据填充进回调函数),动态创建script标签,利用script标签的src属性可以获取任何域下的js脚本,通过这个特性(也可以说漏洞),服务器端不在返货json格式,而是返回一段调用某个函数的js代码,在src中进行了调用,这样实现了跨域.
jsonp优点:
完美解决在测试或者开发中获取不同域下的数据,用户传递一个callback参数给服务端,然后服务端返回数据时会将这个callback参数作为函数名来包裹住JSON数据,这样客户端就可以随意定制自己的函数来自动处理返回数据了。简单来说数据的格式没有发生
很大变化
jsonp缺点:
1.jsonp只支持get请求而不支持post请求,也即是说如果想传给后台一个json格式的数据,此时问题就来了,浏览器会报一个http状态码415错误,告诉你请求格式不正确,(在登录注册中需要给后台传一大串数据),如果都用参数的形式拼接在url后面的话不太现实,后台取值也会显得繁琐,
2.在登录模块中需要用到session来判断当前用户的登录状态,这时候由于是跨域的原因,前后台的取到的session是不一样的,那么就不能就行session来判断.
3.由于jsonp存在安全性问题,为了防止XSS攻击我们的服务器, 我们可以限制域,比如
Access-Control-Allow-Origin: http://blog.csdn.NET
安全防范:
1.防止callback参数意外截断js代码,特殊字符单引号双引号,换行符存在风险.
2.防止callback参数恶意添加script标签,造成xss漏洞
3.防止跨域请求滥用,阻止非法站点恶意调用
12. JSON 和 JSONP 的区别?
一、指代不同
1、duJSON:是一种轻量级的数据交换格式。
2、JSONP:是JSON的一种“使用模式”,可zhi用于解决主流dao浏览器的跨域数据访问的问题。
二、特点不同
1、JSON:基于 ECMAScript (欧洲计算机协会制定的js规范)的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。
2、JSONP:在客户端调用提供JSONP支持的URL Service,获取JSONP格式数据。
三、使用方法不同
1、JSON:简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。
2、JSONP:Callback仅仅是JSONP的简单实现,可以根据具体需要实现更复杂的功能,比如可以在客户端动态集成更多的变量数据来完成分页功能。
11、浏览器存储
1. Cookie、Session、localStorage 分别是什么?
一、cookie
cookie是存储在浏览器上的一小段数据,用来记录某些当页面关闭或者刷新后仍然需要记录的信息。在控制台用 「document.cookie」查看你当前正在浏览的网站的cookie。
cookie可以使用
js 在浏览器直接设置(用于记录不敏感信息,如用户名), 也可以在服务端通使用 HTTP 协议规定的 set-cookie
来让浏览器种下cookie,这是最常见的做法。(打开一个网站,清除全部cookie,然后刷新页面,在network的Response
headers试试找一找set-cookie吧)
每次网络请求 Request headers 中都会带上cookie。所以如果 cookie 太多太大对传输效率会有影响。
一般浏览器存储cookie 最大容量为4k,所以大量数据不要存到cookie。
设置cookie时的参数:
path:表示 cookie 影响到的路径,匹配该路径才发送这个 cookie。expires 和 maxAge:告诉浏览器 cookie 时候过期,maxAge 是 cookie 多久后过期的相对时间。不设置这两个选项时会产生 session cookie,session cookie 是 transient 的,当用户关闭浏览器时,就被清除。一般用来保存 session 的 session_id。
secure:当 secure 值为 true 时,cookie 在 HTTP 中是无效,在 HTTPS 中才有效
httpOnly:浏览器不允许脚本操作 document.cookie 去更改 cookie。一般情况下都应该设置这个为 true,这样可以避免被 xss 攻击拿到 cookie。[cookie 参数][简述 Cookie 是什么]
二、session
当一个用户打开淘宝登录后,刷新浏览器仍然展示登录状态。服务器如何分辨这次发起请求的用户是刚才登录过的用户呢?这里就使用了session保存状态。用户在输入用户名密码提交给服务端,服务端验证通过后会创建一个session用于记录用户的相关信息,这个
session 可保存在服务器内存中,也可保存在数据库中。
创建session后,会把关联的session_id 通过setCookie 添加到http响应头部中。
浏览器在加载页面时发现响应头部有 set-cookie字段,就把这个cookie 种到浏览器指定域名下。
当下次刷新页面时,发送的请求会带上这条cookie, 服务端在接收到后根据这个session_id来识别用户。
cookie 是存储在浏览器里的一小段「数据」,而session是一种让服务器能识别某个用户的「机制」,session 在实现的过程中需要使用cookie。当然有时候说到 session 也指服务器里创建的那个和用户身份关联的对象。
三、localStorage
localStorage HTML5本地存储web storage特性的API之一,用于将大量数据(最大5M)保存在浏览器中,保存后数据永远存在不会失效过期,除非用 js手动清除。
不参与网络传输。一般用于性能优化,可以保存图片、js、css、html 模板、大量数据。
2. Cookie,sessionStorage 和 localStorage 的区别?
一、Cookie、session和localStorage的区别
cookie的内容主要包括:名字、值、过期时间、路径和域。路径与域一起构成cookie的作用范围。若不设置时间,则表示这个cookie的生命期为浏览器会话期间,关闭浏览器窗口,cookie就会消失。这种生命期为浏览器会话期的cookie被称为会话cookie。
会话cookie一般不存储在硬盘而是保存在内存里,当然这个行为并不是规范规定的。若设置了过期时间,浏览器就会把cookie保存到硬盘上,关闭后再打开浏览器这些cookie仍然有效直到超过设定的过期时间。对于保存在内存里的cookie,不同的浏览器有不同的处理方式session机制。
当程序需要为某个客户端的请求创建一个session时,服务器首先检查这个客户端的请求里是否已包含了一个session标识(称为session id),如果已包含则说明以前已经为此客户端创建过session,服务器就按照session id把这个session检索出来使用(检索不到,会新建一个),如果客户端请求不包含session id,则为客户端创建一个session并且生成一个与此session相关联的session id,session id的值应该是一个既不会重复,又不容易被找到规律以仿造的字符串,这个session id将被在本次响应中返回给客户端保存。保存这个session id的方式可以采用cookie,这样在交互过程中浏览器可以自动的按照规则把这个标识发送给服务器。
二、cookie和session的区别:
*1、cookie数据存放在客户的浏览器上,session数据放在服务器上
2、cookie不是很安全,别人可以分析存放在本地的cookie并进行cookie欺骗,考虑*到安全应当使用session
3、session会在一定时间内保存在服务器上,当访问增多,会比较占用你服务器的性能,考虑到减轻服务器性能方面,应当使用cookie
4、单个cookie保存的数*据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie
5、建议将登录信息等重要信息存放为session,其他信息如果需要保留,可以放在cookie中
6、session保存在服务器,客户端不知道其中的信心;cookie保存在客户端,服务器能够知道其中的信息
7、session中保存的是对象,cookie中保存的是字符串
8、session不能区分路径,同一个用户在访问一个网站期间,所有的session在任何一个地方都可以访问到,而cookie中如果设置了路径参数,那么同一个网站中不同路径下的cookie互相是访问不到的*
三、web Storage和Cookie的区别
Web Storage的概念和cookie相似,区别是它是为了更大容量存储设计的,cookie的大小是受限的,并且每次请求一个新的页面的时候cookie都会被发送过去,这样无形中浪费了带宽,另外cookie还需要指定作用域,不可跨域调用。
除此之外,web storage拥有setItem,getItem,removeItem,clear等方法,不像cookie需要前端开发者自己封装setCookie,getCookie。
但是cookie也是不可或缺的,cookie的作用是与服务器进行交互,作为http规范的一部分而存在的,而web Storage仅仅是为了在本地“存储”数据而生
sessionStorage、localStorage、cookie都是在浏览器端存储的数据,其中sessionStorage的概念很特别,引入了一个“浏览器窗口”的概念,sessionStorage是在同源的同窗口中,始终存在的数据,也就是说只要这个浏览器窗口没有关闭,即使刷新页面或进入同源另一个页面,数据仍然存在,关闭窗口后,sessionStorage就会被销毁,同时“独立”打开的不同窗口,即使是同一页面,sessionStorage对象也是不同的
Web Storage带来的好处:
1、减少网络流量:一旦数据保存在本地之后,就可以避免再向服务器请求数据,因此减少不必要的数据请求,减少数
据在浏览器和服务器间不必要的来回传递
2、快速显示数据:性能好,从本地读数据比通过网络从服务器上获得数据快得多,本地数据可以及时获得,再加上网
页本身也可以有缓存,因此整个页面和数据都在本地的话,可以立即显示
3、临时存储:很多时候数据只需要在用户浏览一组页面期间使用,关闭窗口后数据就可以丢弃了,这种情况使用sessionStorage非常方便
四、浏览器本地存储与服务器端存储的区别
其实数据既可以在浏览器本地存储,也可以在服务器端存储
浏览器可以保存一些数据,需要的时候直接从本地存取,sessionStorage、localStorage和cookie都是由浏览器存储在本地的数据
服务器端也可以保存所有用户的所有数据,但需要的时候浏览器要向服务器请求数据。
1、服务器端可以保存用户的持久数据,如数据库和云存储将用户的大量数据保存在服务器端
2、服务器端也可以保存用户的临时会话数据,服务器端的session机制,如jsp的session对象,数据保存在服务器上,
实际上,服务器和浏览器之间仅需传递session id即可,服务器根据session id找到对应用户的session对象,会话数据仅在一段时间内有效,这个时间就是server端设置的session有效期
服务器端保存所有的用户的数据,所以服务器端的开销较大,而浏览器端保存则把不同用户需要的数据分别保存在用户各自的浏览器中,浏览器端一般只用来存储小数据,而非服务可以存储大数据或小数据服务器存储数据安全一些,浏览器只适合存储一般数据
五、sessionStorage、localStorage和cookie的区别
共同点:都是保存在浏览器端、且同源的
区别:
1、cookie数据始终在同源的http请求中携带(即使不需要),即cookie在浏览器和服务器间来回传递,而sessionStorage和localStorage不会自动把数据发送给服务器,仅在本地保存。cookie数据还有路径(path)的概念,可以限制cookie只属于某个路径下
2、存储大小限制也不同,cookie数据不能超过4K,同时因为每次http请求都会携带cookie、所以cookie只适合保存很小的数据,如会话标识。sessionStorage和localStorage虽然也有存储大小的限制,但比cookie大得多,可以达到5M或更大
3、数据有效期不同,sessionStorage:仅在当前浏览器窗口关闭之前有效;localStorage:始终有效,窗口或浏览器关闭也一直保存,因此用作持久数据;cookie:只在设置的cookie过期时间之前有效,即使窗口关闭或浏览器关闭
4、作用域不同,sessionStorage不在不同的浏览器窗口中共享,即使是同一个页面;localstorage在所有同源窗口中都是共享的;cookie也是在所有同源窗口中都是共享的
5、web Storage支持事件通知机制,可以将数据更新的通知发送给监听者
6、web Storage的api接口使用更方便
六、sessionStorage与页面js数据对象的区别
页面中一般的js对象的生存期仅在当前页面有效,因此刷新页面或转到另一页面这样的重新加载页面的情况,数据就不存在了
而sessionStorage只要同源的同窗口中,刷新页面或进入同源的不同页面,数据始终存在,也就是说只要浏览器不关闭,数据仍然存在
3. 如何实现同一个浏览器多个标签页之间的通信?
方法一:使用localStorage
使用localStorage.setItem(key,value);添加内容
使用storage事件监听添加、修改、删除的动作
window.addEventListener("storage",function(event){
$("#name").val(event.key+”=”+event.newValue);
});
方法二、使用cookie+setInterval
HTML代码
<inputid="name"><input type="button" id="btnOK"value="发送">
JS代码-页面1
$(function(){
$("#btnOK").click(function(){
varname=$("#name").val();
document.cookie="name="+name;
});
});
JS代码-页面2
//获取Cookie天的内容
function getKey(key) {
return JSON.parse("{\""+ document.cookie.replace(/;\s+/gim,"\",\"").replace(/=/gim, "\":\"") +"\"}")[key];
}
//每隔1秒获取Cookie的内容
setInterval(function(){
console.log(getKey("name"));
},1000);
4. HTML5 的离线储存怎么使用,工作原理能不能解释一下?
1.在用户没有与因特网连接时,可以正常访问站点或应用,在用户与因特网连接时,更新用户机器上的缓存文件。
2.原理:HTML5的离线存储是基于一个新建的.appcache文件的缓存机制(不是存储技术),通过这个文件上的解析清单离线存储资源,这些资源就会像cookie一样被存储了下来。之后当网络在处于离线状态下时,浏览器会通过被离线存储的数据进行页面展示
3.如何使用
页面头部像下面一样加入一个manifest的属性;
在cache.manifest文件的编写离线存储的资源
在离线状态时,操作window.applicationCache进行需求实现
CACHE MANIFEST
#v0.11
CACHE:
js/app.js
css/style.css
NETWORK:
resourse/logo.png
FALLBACK:
/offline.html
5. 浏览器是怎么对 HTML5 的离线储存资源进行管理和加载的呢?
在线的情况下,浏览器发现html头部有manifest属性,它会请求manifest文件,如果是第一次访问app,那么浏览器就会根据manifest文件的内容下载相应的资源并且进行离线存储。如果已经访问过app并且资源已经离线存储了,那么浏览器就会使用离线的资源加载页面,然后浏览器会对比新的manifest文件与旧的manifest文件,如果文件没有发生改变,就不做任何操作,如果文件改变了,那么就会重新下载文件中的资源并进行离线存储。
离线的情况下,浏览器就直接使用离线存储的资源。
6. Web 开发中会话跟踪的方法有哪些?
1.隐藏表单域:<input type="hidden">非常适合步需要大量数据存储的会话应用。
2.URL 重写:URL 可以在后面附加参数,和服务器的请求一起发送,这些参数为名字/值对。
3.Cookie:一个 Cookie 是一个小的,已命名数据元素。服务器使用 SET-Cookie 头标将它作为 HTTP响应的一部分传送到客户端,客户端被请求保存 Cookie 值,在对同一服务器的后续请求使用一个Cookie 头标将之返回到服务器。与其它技术比较,Cookie 的一个优点是在浏览器会话结束后,甚至在客户端计算机重启后它仍可以保留其值。
4.Session:使用 setAttribute(String str,Object obj)方法将对象捆绑到一个会话
5.IP地址
7. 使用 localStorage 封装一个 Storage 对象,达到如下效果:
Storage.set("name", "前端一万小时") // 设置 name 字段存储的值为“前端一万小时”。
Storage.set("age", 2, 30);
Storage.set("people", ["Oli", "Aman", "Dante"]
, 60)
Storage.get("name") // "前端一万小时"
Storage.get("age") /*
如果不超过 30 秒,返回数字类型的 2;如果超过 30 秒,返回 undefined,
并且 localStorage 里清除 age 字段。
*/
Storage.get("people") // 如果不超过 60 秒,返回数组; 如果超过 60 秒,返回 undefined。
12、前端工程化
1. 模块化开发怎么做?
1. 模块就是一个有特定功能的文件,我们可以通过加载这些模块得到特定的功能
2. 模块化开发就是js的功能分离,通过需求引入不同的文件
3. 模块化开发可以使代码耦合度降低,避免代码多次在页面出现,他最大的作用就是重用
模块开发要遵循的规范
1. AMD规范也叫异步模块加载规范,在这个规范下模块会异步加载,不影响后面语句的执行,我们可以使用define定义模块,使用require调用模块
2. CommonJS规范是服务器端模块的规范,node.js就采用了这个规范,每个模块都有一个单独的作用域,模块内部的变量无法被其他模块读取,除非定义为global的对象和属性
3. CMD规范通用模块定义.CMD是按需加载,一个模块就是一个文件
2.谈谈你对 AMD、CMD 的理解?
一、模块
模块化:是一种处理复杂系统分解为代码结构更合理,可维护性更高的可管理的模块的方式。
在理想状态下我们只需要完成自己部分的核心业务逻辑代码,其他方面的依赖可以通过直接加载被人已经写好模块进行使用即可。
无模块
优点:
相比于使用一个js文件,这种多个js文件实现最简单的模块化的思想是进步的。
缺点:
污染全局作用域。 因为每一个模块都是暴露在全局的,简单的使用,会导致全局变量命名冲突,当然,我们也可以使用命名空间的方式来解决。
对于大型项目,各种js很多,开发人员必须手动解决模块和代码库的依赖关系,后期维护成本较高。 依赖关系不明显,不利于维护。
比如main.js需要使用jquery,但是,从上面的文件中,我们是看不出来的,如果jquery忘记了,那么就会报错。
二、CommonJS
CommonJs 是服务器端模块的规范,Node.js采用了这个规范。
根据CommonJS规范,一个单独的文件就是一个模块。加载模块使用require方法,该方法读取一个文件并执行,最后返回文件内部的exports对象。
var math=require('math');math.add(2,3);
第二行math.add(2, 3),在第一行require('math')之后运行,因此必须等math.js加载完成。也就是说,如果加载时间很长,整个应用就会停在那里等。您会注意到require是同步的。
CommonJS 加载模块是同步的,所以只有加载完成才能执行后面的操作。像Node.js主要用于服务器的编程,加载的模块文件一般都已经存在本地硬盘,所以加载起来比较快,不用考虑异步加载的方式,所以CommonJS规范比较适用。但如果是浏览器环境,要从服务器加载模块,这是就必须采用异步模式。所以就有了 AMD CMD 解决方案。
三、AMD
AMD 即AsynchronousModule Definition,中文名是异步模块定义的意思。它是一个在浏览器端模块化开发的规范
AMD也采用require()语句加载模块,但是不同于CommonJS,它要求两个参数:
require([module], callback);
第一个参数[module],是一个数组,里面的成员就是要加载的模块;第二个参数callback,则是加载成功之后的回调函数。如果将前面的代码改写成AMD形式,就是下面这样:
require(['math'],function(math){ math.add(2,3);});
math.add()与math模块加载不是同步的,浏览器不会发生假死。所以很显然,AMD比较适合浏览器环境。目前,主要有两个Javascript库实现了AMD规范:require.js和curl.js。
与 RequireJS
AMD 是 RequireJS 在推广过程中对模块定义的规范化产出
AMD异步加载模块。它的模块支持对象 函数 构造器 字符串 JSON等各种类型的模块。
//通过数组引入依赖 ,回调函数通过形参传入依赖define(['Module1', ‘Module2’],function(Module1, Module2){functionfoo(){/// someing Module1.test();}return{foo: foo}});
第一个参数 id 为字符串类型,表示了模块标识,为可选参数。若不存在则模块标识应该默认定义为在加载器中被请求脚本的标识。如果存在,那么模块标识必须为顶层的或者一个绝对的标识。
第二个参数,dependencies ,是一个当前模块依赖的,已被模块定义的模块标识的数组字面量。
第三个参数,factory,是一个需要进行实例化的函数或者一个对象。
创建模块标识为 Module1 的模块,依赖于 require, export,和标识为 beta 的模块
AMD规范允许输出模块兼容CommonJS规范,这时define方法如下:
define(function(require, exports, module){var reqModule=require("./someModule"); requModule.test(); exports.asplode=function(){//someing}});
优点:
适合在浏览器环境中异步加载模块。可以并行加载多个模块。缺点:
提高了开发成本,并且不能按需加载,而是必须提前加载所有的依赖。
四、CMD
CMD是SeaJS 在推广过程中对模块定义的规范化产出
CMD和AMD的区别有以下几点:
1.对于依赖的模块AMD是提前执行,CMD是延迟执行。不过RequireJS从2.0开始,也改成可以延迟执行(根据写法不同,处理方式不通过)。
2.AMD推崇依赖前置(在定义模块的时候就要声明其依赖的模块),CMD推崇依赖就近(只有在用到某个模块的时候再去require——按需加载)。
//AMDdefine(['./a','./b'],function(a, b){//依赖一开始就写好 a.test(); b.test();});//CMDdefine(function(requie, exports, module){//依赖可以就近书写var a=require('./a'); a.test();...//软依赖if(status){var b=requie('./b'); b.test();}});
3.AMD的api默认是一个当多个用,CMD严格的区分推崇职责单一。例如:AMD里require分全局的和局部的。CMD里面没有全局的 require,提供 seajs.use()来实现模块系统的加载启动。CMD里每个API都简单纯粹。
AMD 是 RequireJS 在推广过程中对模块定义的规范化产出,CMD是SeaJS 在推广过程中被广泛认知。RequireJs出自dojo加载器的作者James Burke,SeaJs出自国内前端大师玉伯。二者的区别,玉伯在12年如是说:
RequireJS 和 SeaJS 都是很不错的模块加载器,两者区别如下:
1. 两者定位有差异。RequireJS 想成为浏览器端的模块加载器,同时也想成为 Rhino/ Node 等环境的模块加载器。SeaJS 则专注于 Web 浏览器端,同时通过 Node 扩展的方式可以很方便跑在 Node 服务器端2. 两者遵循的标准有差异。RequireJS 遵循的是 AMD(异步模块定义)规范,SeaJS 遵循的是 CMD (通用模块定义)规范。规范的不同,导致了两者API 的不同。SeaJS 更简洁优雅,更贴近 CommonJS Modules/1.1 和 Node Modules 规范。3. 两者社区理念有差异。RequireJS 在尝试让第三方类库修改自身来支持 RequireJS,目前只有少数社区采纳。SeaJS 不强推,而采用自主封装的方式来“海纳百川”,目前已有较成熟的封装策略。4. 两者代码质量有差异。RequireJS 是没有明显的 bug,SeaJS 是明显没有 bug。5. 两者对调试等的支持有差异。SeaJS 通过插件,可以实现 Fiddler 中自动映射的功能,还可以实现自动 combo 等功能,非常方便便捷。RequireJS无这方面的支持。6. 两者的插件机制有差异。RequireJS 采取的是在源码中预留接口的形式,源码中留有为插件而写的代码。SeaJS 采取的插件机制则与 Node 的方式一致开放自身,让插件开发者可直接访问或修改,从而非常灵活,可以实现各种类型的插件。
优点:同样实现了浏览器端的模块化加载。 可以按需加载,依赖就近。
缺点:依赖SPM打包,模块的加载逻辑偏重。
五、 ES6 模块
CommonJS
对于基本数据类型,属于复制。即会被模块缓存。同时,在另一个模块可以对该模块输出的变量重新赋值。
对于复杂数据类型,属于浅拷贝。由于两个模块引用的对象指向同一个内存空间,因此对该模块的值做修改时会影响另一个模块。
当使用require命令加载某个模块时,就会运行整个模块的代码。
当使用require命令加载同一个模块时,不会再执行该模块,而是取到缓存之中的值。也就是说,CommonJS模块无论加载多少次,都只会在第一次加载时运行一次,以后再加载,就返回第一次运行的结果,除非手动清除系统缓存。
循环加载时,属于加载时执行。即脚本代码在require的时候,就会全部执行。一旦出现某个模块被"循环加载",就只输出已经执行的部分,还未执行的部分不会输出。
ES6模块
ES6模块中的值属于【动态只读引用】。
对于只读来说,即不允许修改引入变量的值,import的变量是只读的,不论是基本数据类型还是复杂数据类型。当模块遇到import命令时,就会生成一个只读引用。等到脚本真正执行时,再根据这个只读引用,到被加载的那个模块里面去取值。
对于动态来说,原始值发生变化,import加载的值也会发生变化。不论是基本数据类型还是复杂数据类型。
循环加载时,ES6模块是动态引用。只要两个模块之间存在某个引用,代码就能够执行。
3. Webpack 如何实现打包的?
1.新建为webpack.config.js命名的文件,可以直接webpack命令打包
2.webpack 入口文件<app.js> -o 输出文件<bundle.js>
3.webpack --config 你自定义的文件名字<webpack-default.js>