在HTML文档里嵌入客户端JavaScript代码有4种方法:
和
标签对之间。
标签的src属性指定的外部文件中。有个编程哲学叫“unobtrusive JavaScript”,主张内容(HTML)和行为(JavaScript代码)应该尽量地保持分离。根据这个编程哲学,JavaScript最好通过元素的src属性来嵌入HTML文档里。
标签对之间使用在XHTML中,标签中的内容被当做其他内容一样对待。如果JavaScript代码包含”<”或”&”字符,那么这些字符就被解释为XML标记。因此如果要使用XHTML,最好把所有的JavaScript代码放入到一个CDATA部分里:
<script>
// 这里放置JavaScript代码
]]>
script>
在URL后面跟一个javascript:协议限定符,是另一种嵌入JavaScript代码到客户端的方式。javascript: URL可以用在可以使用常规URL的任意地方:比如标记的href属性,
的action属性,甚至window.open()方法的参数。
<a href="javascript:new Date().toLocaleTimeString();">
What time is it ?
a>
就像单击一个URL链接,浏览器会擦除当前文档并显示新文档。上例中将显示当地时间。
元素时,默认先执行脚本,然后再恢复文档的解析和渲染。
标签中使用async属性,则脚本执行的同时,可以进行文档的解析。
标签中使用defer属性,则当文档解析完成后,才会执行脚本。// 脚本执行的同时进行文档解析
<script async src="async.js">script>
// 文档解析完成后才执行脚本
<script defer src="deferred.js">script>
有些事件的目标是文档元素,它们会经常往上传递给文档树,这个过程叫做“冒泡”。
例如,如果用户在元素上单击鼠标,单击事件就会在按钮上触发。如果注册在按钮上的函数没有处理该事件,事件会冒泡到按钮嵌套的容器元素,这样,任何注册在容器元素上的单击事件都会调用。
JavaScript语言并不包含任何线程机制,只是单线程工作,永远不需要担心锁、死锁和竞争条件。
HTML5定义了一种后台线程”WebWorker”,但是JavaScript还是严格的单线程一样工作。
这个阶段document.readystate属性的值是”loading”.
元素时,会把这些元素添加到文档中,然后执行脚本,
解析器会暂时停止,此时脚本如果执行document.write()把文本插入到输入流中,解析器恢复时这些文本会成为文档的一部分。
元素时,它开始下载脚本文本,并继续解析文档。脚本会在它下载完成后尽快执行,但是解析器没有停下来。异步脚本禁止使用document.write()方法。
元素时,脚本会按它们的出现顺序执行,
异步脚本可能在这个时间还在执行。延迟脚本禁止使用document.write()方法。
当文档完成解析,document.readystate属性的值是”interactive”.
document.readystate属性的值是”complete”.
IE支持条件注释(由IE5引入),尽管这种做法并不符合标准规范,但是在处理不兼容性时非常有用。
由于IE不支持canvas,而其他浏览器是支持的,那么为了兼容性,可以添加条件注释如下:
// 只有在IE浏览器中才加载js文件
可以通过通过条件注释完成在不同的浏览器中执行不同的代码:
/*@cc_on
@if (@_jscript)
// 在IE中@_jscript是解释器的名字,值为true
alert("你在使用IE浏览器");
@else*/
// 这段代码并没在JavaScript注释中,但仍然在IE条件注释中
// 也就是说除了IE之外的所有浏览器都执行这里的代码
alert("你在使用非IE浏览器");
/*@end
@*/
脚本只能读取和所属文档来源相同的窗口和文档的属性。脚本本身的来源和同源策略并不相关,相关的是脚本所嵌入的文档的来源。
例如,一个来自主机A的脚本被包含到宿主B的一个Web页面中,那么脚本能完整地访问包含它的文档内容(B的web页面),如果脚本打开一个新窗口并载入来自主机B的另一个文档,脚本对这个文档的内容也具有完全的访问权限。但是,如果脚本打开第三个窗口并载入一个来自主机C的文档,同源策略就会发挥作用,阻止脚本访问这个文档。
Document对象的domain属性
同源策略给那些使用多个子域的大站点带来了一些问题。例如,来自home.example.com的文档里的脚本想要合法地读取developer.example.com载入的文档的属性。为了支持这种类型的多域名站点,可以使用Document对象的domain属性。
如果两个窗口(或窗体)包含的脚本把domain设置成相同的值,那么这两个窗口就不再受同源策略的约束,它们可以相互读取对方的属性。
跨域资源共享 Cross-Origin Resource Sharing
这个标准草案用新的“Origin:”请求头和新的Access-Control-Allow-Origin响应头来扩展HTTP。它允许服务器用头信息显式地列出源,或使用通配符来匹配所有的源并允许由任何地址请求文件。
跨文档消息 cross-document messaging
这是一种新技术,允许来自一个文档的脚本可以传递文本消息(调用window对象的postMessage()方法)到另一个文档里的脚本,而不管脚本的来源是否相同。
跨站脚本,或者叫XSS,表示攻击者向目标web站点注入HTML标签或者脚本。防止XSS攻击是服务器端web开发者的一项基本工作,然而客户端JavaScript程序员也必须预防跨站脚本。
如果web页面动态地产生文档内容,并且文档内容是基于用户提交的数据,而并没有从中移除任何嵌入的HTML标签的话,那么这个web页面很容易遭到跨站脚本攻击。
<script>
// 获取URL中以"?"开始的部分
var name = decodeURIComponent(window.location.search.substring(1)) || "";
document.write("Hello" + name);
script>
http://www.example.com/greet.html?David
,那么文档将显示”Hello David”。http://www.example.com/greet.html?name=%3Cscript src=siteB/evil.js%3E%3C/script%3E
(%3C和%3E是尖括号的编码),那么就会遭到B站点的evil.js脚本注入,evil.js脚本此时将可以对站点A的内容进行任何想要的操作。通常,防止XSS攻击的方式是,在使用任何不可信的数据来动态创建文档内容之前,从中移除HTML标签。
name = name.replace(/"<").replace(/>/g, ">");