标准参考
脚本使用的语言由 SCRIPT 标签的 “type” 属性指定,该属性大小写不敏感,在 HTML 4.01 规范中,该属性没有默认值,而在 HTML 5 草案中,该属性的默认值为 "text/javascript" " 。
SCRIPT 标签的 "language" 属性,用来指定 SCRIPT 标记内的脚本语言类型。该属性已被废弃,HTML 4.01 规范中推荐使用 "type" 来代替。
关于 SCRIPT 标签的更多信息,请参考 HTML 4.01 规范 18.2.1 及 HTML5 草案 4.3.1 中的内容。
“type” 和 "language" 这两个属性在现有浏览器中均支持。
问题描述
当一个 SCRIPT 标签设置了非 "type=text/javascript" 或 ”language=javascript" 时,如:"type="text/JScript1"" 或 "language="JScript"" 情况,各浏览器对 SCRIPT 标签识别情况不一致。
注1:JScript 是 ECMAScript 的微软实现版,类似其他浏览器的 JavaScript,但有些细节上有差异。
造成的影响
该问题将导致部分脚本在各浏览器中识别程度不一,导致某些标示的脚本不能被解析和运行。
受影响的浏览器
所有浏览器 |
---|
问题分析
SCRIPT 标签的 “type” 属性用来指定嵌入脚本代码的语言类型,它是一个 MIME 类型的值,关于 MIME 请参考 RFC2045 和 RFC2046 中的说明。
“type” 属性值的大小写不敏感。 同样 "language" 属性也是用来指定嵌入脚本代码语言类型的,属性值也不区分大小写。
我们构造一些系列常见 “type” 和 "language" 属性值,观察各浏览器对他们的支持情况。
分析以下代码:
Script Type: text/javascript: <script type='text/javascript'>document.write('OK');</script> text/ecmascript: <script type='text/ecmascript'>document.write('OK');</script> text/livescript: <script type='text/livescript'>document.write('OK');</script> text/javascript1.0: <script type='text/javascript1.0'>document.write('OK')</script> text/javascript1.1: <script type='text/javascript1.1'>document.write('OK')</script> text/javascript1.2: <script type='text/javascript1.2'>document.write('OK')</script> text/javascript1.3: <script type='text/javascript1.3'>document.write('OK')</script> text/javascript1.4: <script type='text/javascript1.4'>document.write('OK')</script> text/javascript1.5: <script type='text/javascript1.5'>document.write('OK')</script> text/javascript1.6: <script type='text/javascript1.6'>document.write('OK')</script> text/javascript1.7: <script type='text/javascript1.7'>document.write('OK')</script> text/jscript: <script type='text/jscript'>document.write('OK')</script> text/vbscript: <script type='text/vbscript'>document.write("OK")</script> text/vbs: <script type='text/vbs'>document.write("OK")</script> application/javascript: <script type='application/javascript'>document.write('OK')</script> text/javascript && language=vbs: <script type='text/javascript' language='vbs'>document.write('OK');</script> Language: javascript: <script language="javascript">document.write('OK')</script> ecmascript: <script language="ecmascript">document.write('OK')</script> livescript: <script language="livescript">document.write('OK')</script> javascript1.0: <script language="javascript1.0">document.write('OK')</script> javascript1.1: <script language="javascript1.1">document.write('OK')</script> javascript1.2: <script language="javascript1.2">document.write('OK')</script> javascript1.3: <script language="javascript1.3">document.write('OK')</script> javascript1.4: <script language="javascript1.4">document.write('OK')</script> javascript1.5: <script language="javascript1.5">document.write('OK')</script> javascript1.6: <script language="javascript1.6">document.write('OK')</script> javascript1.7: <script language="javascript1.7">document.write('OK')</script> jscript: <script language="jscript">document.write('OK')</script> vbscript: <script language="vbscript">document.write("OK")</script> vbs: <script language="vbs">document.write("OK")</script> Language Encode: javascript.encode: <script language="javascript.encode">document.write('OK')</script> ecmascript.encode: <script language="ecmascript.encode">document.write('OK')</script> livescript.encode: <script language="livescript.encode">document.write('OK')</script> javascript1.1.encode: <script language="javascript1.1.encode">document.write('OK')</script> javascript1.7.encode: <script language="javascript1.7.encode">document.write('OK')</script> jscript.encode: <script language="jscript.encode">document.write('OK')</script> vbscript.encode: <script language="vbscript.encode">document.write("OK")</script> vbs.encode: <script language="vbs.encode">document.write("OK")</script>
这段代码在不同浏览器中的结果如下:
IE6 IE7 IE8 | Firefox | Chrome Safari | Opera | |
---|---|---|---|---|
Script Type | text/javascript: OK text/ecmascript: OK text/livescript: OK text/javascript1.0: text/javascript1.1: OK text/javascript1.2: OK text/javascript1.3: OK text/javascript1.4: text/javascript1.5: text/javascript1.6: text/javascript1.7: text/jscript:OK text/vbscript: OK text/vbs: OK application/javascript: text/javascript && language=vbs: OK | text/javascript: OK text/ecmascript: OK text/livescript: text/javascript1.0: text/javascript1.1: text/javascript1.2: text/javascript1.3: text/javascript1.4: text/javascript1.5: text/javascript1.6: text/javascript1.7: text/jscript text/vbscript: text/vbs: application/javascript: OK text/javascript && language=vbs: OK | text/javascript: OK text/ecmascript: OK text/livescript: OK text/javascript1.0: OK text/javascript1.1: OK text/javascript1.2: OK text/javascript1.3: OK text/javascript1.4: text/javascript1.5: text/javascript1.6: text/javascript1.7: text/jscript:OK text/vbscript: text/vbs: application/javascript: OK text/javascript && language=vbs: OK | text/javascript: OK text/ecmascript: OK text/livescript: text/javascript1.0: text/javascript1.1: text/javascript1.2: text/javascript1.3: text/javascript1.4: text/javascript1.5: text/javascript1.6: text/javascript1.7: text/jscript:OK text/vbscript: text/vbs: application/javascript: OK text/javascript && language=vbs: OK |
Language | javascript: OK ecmascript: OK livescript: OK javascript1.0: javascript1.1: OK javascript1.2: OK javascript1.3: OK javascript1.4: javascript1.5: javascript1.6: javascript1.7: jscript: OK vbscript: OK vbs: OK | javascript: OK ecmascript: livescript: OK javascript1.0: OK javascript1.1: OK javascript1.2: OK javascript1.3: OK javascript1.4: OK javascript1.5: OK javascript1.6: OK javascript1.7: OK jscript: vbscript: vbs: | javascript: OK ecmascript: OK livescript: OK javascript1.0: OK javascript1.1: OK javascript1.2: OK javascript1.3: OK javascript1.4: OK javascript1.5: OK javascript1.6: OK javascript1.7: OK jscript: OK vbscript: vbs: | javascript: OK ecmascript: OK livescript: OK javascript1.0: OK javascript1.1: OK javascript1.2: OK javascript1.3: OK javascript1.4: OK javascript1.5: OK javascript1.6: javascript1.7: jscript: OK vbscript: vbs: |
Language Encode 1 | javascript.encode: ecmascript.encode: livescript.encode: javascript1.1.encode: javascript1.7.encode: jscript.encode: OK vbscript.encode: OK vbs.encode: | javascript.encode: ecmascript.encode: livescript.encode: javascript1.1.encode: javascript1.7.encode: jscript.encode: vbscript.encode: vbs.encode: | javascript.encode: ecmascript.encode: livescript.encode: javascript1.1.encode: javascript1.7.encode: jscript.encode: vbscript.encode: vbs.encode: | javascript.encode: ok ecmascript.encode: livescript.encode: ok javascript1.1.encode: javascript1.7.encode: jscript.encode: vbscript.encode: vbs.encode: |
【注】:Encode 关键字代表了 Microsoft 提供的脚本加密(Script Encoder)机制,可以对脚本进行加密,包括 JScript 和 VBScript。经过加密的脚本,仅在 IE 下能正常运行,其它浏览器下不识别。这里的 Language Encode 仅代表对类似脚本类声明的支持程度,并不代表可以执行的浏览器就一定支持 Microsoft 的脚本加密(Script Encoder)机制。
更详细信息可以参考:BT9006: 只有 IE 的脚本引擎支持 JScript.Encode 和 VBScript.Encode
根据上表可以看出,各浏览器对于 "type" 和 "language" 属性本身均支持,但是对于其中设置的脚本语言类型识别与支持各异:
- "type" 和 "language" 同时存在时,所有浏览器均优先识别 "type" 属性内的脚本类型;
- 其中 IE 浏览器实际支持 JScript 和 VBScript 脚本语言标示以及 Script Encoder 加密;
- Firefox Chrome Safari Opera 对 "type" 属性值的具体识别宽容度不一致,相对 Chrome Safari 对属性值正确性校验更加宽松,Firefox 的校验最为严格;
- 在 "Language" 属性值识别宽容度比较中,各浏览器中 Chrome Safari 依然最为宽松,IE 最为严格,Firefox 与 Opera 持平;
- Language Encode 比较中,只有 IE 支持 JScript.Encoder 以及 VBScript.Encoder 类型设置,Firefox Chrome Safari均不支持,Opera 中则是该属性值被修复为默认的 Javascript 脚本语言后才有输出值。
解决方案
为了保证脚本程序可以正常执行,除非特意使用仅 IE 支持的 VBScript 和 Script Encoder 机制外,应当将 SCRIPT 标记的 "type" 属性设置为 "javascript",并且不要设置已经废弃的 "Languange" 属性。