同源限制
浏览器安全的基石是“同源政策”(same-origin
policy)。很多开发者都知道这一点,但了解得不全面。
概述
含义
1995年,同源政策由 Netscape
公司引入浏览器。目前,所有浏览器都实行这个政策。
最初,它的含义是指,A 网页设置的 Cookie,B
网页不能打开,除非这两个网页“同源”。所谓“同源”指的是“三个相同”。
协议相同
域名相同
端口相同(这点可以忽略,详见下文)
举例来说,[http://www.example.com/dir/page.html](http://www.example.com/dir/page.html)这个网址,协议是http://,域名是www.example.com,端口是80(默认端口可以省略),它的同源情况如下。
http://www.example.com/dir2/other.html:同源
http://example.com/dir/other.html:不同源(域名不同)
http://v2.www.example.com/dir/other.html:不同源(域名不同)
http://www. ...
XMLHttpRequest 对象
简介
浏览器与服务器之间,采用 HTTP
协议通信。用户在浏览器地址栏键入一个网址,或者通过网页表单向服务器提交内容,这时浏览器就会向服务器发出
HTTP 请求。
1999年,微软公司发布 IE 浏览器5.0版,第一次引入新功能:允许
JavaScript 脚本向服务器发起 HTTP
请求。这个功能当时并没有引起注意,直到2004年 Gmail 发布和2005年 Google
Map 发布,才引起广泛重视。2005年2月,AJAX 这个词第一次正式提出,它是
Asynchronous JavaScript and XML 的缩写,指的是通过 JavaScript
的异步通信,从服务器获取 XML
文档从中提取数据,再更新当前网页的对应部分,而不用刷新整个网页。后来,AJAX
这个词就成为 JavaScript 脚本发起 HTTP
通信的代名词,也就是说,只要用脚本发起通信,就可以叫做 AJAX 通信。W3C
也在2006年发布了它的国际标准。
具体来说,AJAX 包括以下几个步骤。
创建 XMLHttpRequest 实例
发出 HTTP 请求
接 ...
Cookie
概述
Cookie
是服务器保存在浏览器的一小段文本信息,一般大小不能超过4KB。浏览器每次向服务器发出请求,就会自动附上这段信息。
HTTP 协议不带有状态,有些请求需要区分状态,就通过 Cookie
附带字符串,让服务器返回不一样的回应。举例来说,用户登录以后,服务器往往会在网站上留下一个
Cookie,记录用户编号(比如id=1234),以后每次浏览器向服务器请求数据,就会带上这个字符串,服务器从而知道是谁在请求,应该回应什么内容。
Cookie
的目的就是区分用户,以及放置状态信息,它的使用场景主要如下。
对话(session)管理:保存登录状态、购物车等需要记录的信息。
个性化信息:保存用户的偏好,比如网页的字体大小、背景色等等。
追踪用户:记录和分析用户行为。
Cookie
不是一种理想的客户端存储机制。它的容量很小(4KB),缺乏数据操作接口,而且会影响性能。客户端存储建议使用
Web storage API 和
IndexedDB。只有那些每次请求都需要让服务器知道的信息,才应该放在 Cookie
里面。
每个 Cookie 都有以下几方面的元数据。
...
Navigator 对象,Screen 对象。
window.navigator属性指向一个包含浏览器和系统信息的
Navigator 对象。脚本通过这个属性了解用户的环境信息。
Navigator 对象的属性
Navigator.userAgent
navigator.userAgent属性返回浏览器的 User Agent
字符串,表示用户设备信息,包含了浏览器的厂商、版本、操作系统等信息。
下面是 Chrome 浏览器的userAgent。
12navigator.userAgent// "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.57 Safari/537.36"
通过userAgent属性识别浏览器,不是一个好办法。因为必须考虑所有的情况(不同的浏览器,不同的版本),非常麻烦,而且用户可以改变这个字符串。这个字符串的格式并无统一规定,也无法保证未来的适用性,各种上网设备层出不穷,难以穷尽。所以,现在一般不再通过它识别浏览器 ...
window 对象
概述
浏览器里面,window对象(注意,w为小写)指当前的浏览器窗口。它也是当前页面的顶层对象,即最高一层的对象,所有其他对象都是它的下属。一个变量如果未声明,那么默认就是顶层对象的属性。
12a = 1;window.a // 1
上面代码中,a是一个没有声明就直接赋值的变量,它自动成为顶层对象的属性。
window有自己的实体含义,其实不适合当作最高一层的顶层对象,这是一个语言的设计失误。最早,设计这门语言的时候,原始设想是语言内置的对象越少越好,这样可以提高浏览器的性能。因此,语言设计者
Brendan Eich
就把window对象当作顶层对象,所有未声明就赋值的变量都自动变成window对象的属性。这种设计使得编译阶段无法检测出未声明变量,但到了今天已经没有办法纠正了。
window 对象的属性
window.name
window.name属性是一个字符串,表示当前浏览器窗口的名字。窗口不一定需要名字,这个属性主要配合超链接和表单的target属性使用。
123window.name = 'Hello World!';consol ...
浏览器环境概述
JavaScript 是浏览器的内置脚本语言。也就是说,浏览器内置了 JavaScript
引擎,并且提供各种接口,让 JavaScript
脚本可以控制浏览器的各种功能。一旦网页内嵌了 JavaScript
脚本,浏览器加载网页,就会去执行脚本,从而达到操作浏览器的目的,实现网页的各种动态效果。
本章开始介绍浏览器提供的各种 JavaScript 接口。首先,介绍 JavaScript
代码嵌入网页的方法。
代码嵌入网页的方法
网页中嵌入 JavaScript 代码,主要有四种方法。
<script>元素直接嵌入代码。
<script>标签加载外部脚本
事件属性
URL 协议
script 元素嵌入代码
<script>元素内部可以直接写入 JavaScript 代码。
1234<script> var x = 1 + 5; console.log(x);</script>
<script>标签有一个type属性,用来指定脚本类型。对
JavaScript 脚本来说,type属性可以设为 ...
GlobalEventHandlers 接口
指定事件的回调函数,推荐使用的方法是元素的addEventListener方法。
1div.addEventListener('click', clickHandler, false);
除了之外,还有一种方法可以直接指定事件的回调函数。
1div.onclick = clickHandler;
这个接口是由GlobalEventHandlers接口提供的。它的优点是使用比较方便,缺点是只能为每个事件指定一个回调函数,并且无法指定事件触发的阶段(捕获阶段还是冒泡阶段)。
HTMLElement、Document和Window都继承了这个接口,也就是说,各种
HTML
元素、document对象、window对象上面都可以使用GlobalEventHandlers接口提供的属性。下面就列出这个接口提供的主要的事件属性。
GlobalEventHandlers.onabort
某个对象的abort事件(停止加载)发生时,就会调用onabort属性指定的回调函数。
各种元素的停止加载事件,到底如何触发,目前并没有统一的规定 ...
其他常见事件
资源事件
beforeunload 事件
beforeunload事件在窗口、文档、各种资源将要卸载前触发。它可以用来防止用户不小心卸载资源。
如果该事件对象的returnValue属性是一个非空字符串,那么浏览器就会弹出一个对话框,询问用户是否要卸载该资源。但是,用户指定的字符串可能无法显示,浏览器会展示预定义的字符串。如果用户点击“取消”按钮,资源就不会卸载。
123window.addEventListener('beforeunload', function (event) { event.returnValue = '你确定离开吗?';});
上面代码中,用户如果关闭窗口,浏览器会弹出一个窗口,要求用户确认。
浏览器对这个事件的行为很不一致,有的浏览器调用event.preventDefault(),也会弹出对话框。IE
浏览器需要显式返回一个非空的字符串,才会弹出对话框。而且,大多数浏览器在对话框中不显示指定文本,只显示默认文本。因此,可以采用下面的写法,取得最大的兼容性。
123456windo ...
拖拉事件
拖拉事件的种类
拖拉(drag)指的是,用户在某个对象上按下鼠标键不放,拖动它到另一个位置,然后释放鼠标键,将该对象放在那里。
拖拉的对象有好几种,包括元素节点、图片、链接、选中的文字等等。在网页中,除了元素节点默认不可以拖拉,其他(图片、链接、选中的文字)都可以直接拖拉。为了让元素节点可拖拉,可以将该节点的draggable属性设为true。
123<div draggable="true"> 此区域可拖拉</div>
上面代码的div区块,在网页中可以直接用鼠标拖动。松开鼠标键时,拖动效果就会消失,该区块依然在原来的位置。
draggable属性可用于任何元素节点,但是图片(<img>)和链接(<a>)不加这个属性,就可以拖拉。对于它们,用到这个属性的时候,往往是将其设为false,防止拖拉这两种元素。
注意,一旦某个元素节点的draggable属性设为true,就无法再用鼠标选中该节点内部的文字或子节点了。
当元素节点或选中的文本被拖拉时,就会持续触发拖拉事件,包括以下一些事件。
drag:拖拉过 ...
触摸事件
触摸操作概述
浏览器的触摸 API 由三个部分组成。
Touch:一个触摸点
TouchList:多个触摸点的集合
TouchEvent:触摸引发的事件实例
Touch接口的实例对象用来表示触摸点(一根手指或者一根触摸笔),包括位置、大小、形状、压力、目标元素等属性。有时,触摸动作由多个触摸点(多根手指)组成,多个触摸点的集合由TouchList接口的实例对象表示。TouchEvent接口的实例对象代表由触摸引发的事件,只有触摸屏才会引发这一类事件。
很多时候,触摸事件和鼠标事件同时触发,即使这个时候并没有用到鼠标。这是为了让那些只定义鼠标事件、没有定义触摸事件的代码,在触摸屏的情况下仍然能用。如果想避免这种情况,可以用event.preventDefault方法阻止发出鼠标事件。
Touch 接口
Touch 接口概述
Touch
接口代表单个触摸点。触摸点可能是一根手指,也可能是一根触摸笔。
浏览器原生提供Touch构造函数,用来生成Touch实例。
1var touch = new Touch(touchOptions);
Touch构造函数接受一个配置对象作为参 ...
