美文网首页
动态修改script标签中的src属性存在的问题

动态修改script标签中的src属性存在的问题

作者: goddyzhao | 来源:发表于2015-07-25 10:35 被阅读3339次

今天某个同事遇到一个诡异的问题,问题描述如下:

需求:通过脚本动态修改script标签的src来载入一段外部脚本并执行
实现方式(#1)

<script type="text/javascript" id="external-script">
</script>
<script type="text/javascript">
    document.getElementById('external-script').src='url2';
</script>

url2的内容如下

alert('I am dynamic');

结果

  • Chrome: 什么事都没发生(没有请求url2)
  • Firefox: 什么事都没发生(没有请求url2)
  • IE9:什么事都没发生(请求url2但不执行url2的脚本)
  • IE(6,7,8): I am dynamic(请求并执行了url2的脚本)

注意实现方式中,第一段的script标签中间是有内容的(空格、换行符以及回车符)。

如何来解释这个问题呢?要解释这个问题,我们来看两个变种的例子,第一个例子(明确内联内容),如下所示(#2):

<script type="text/javascript" id="external-script">
alert('I am inline');
</script>
<script type="text/javascript">
    document.getElementById('external-script').src='url2';
</script>

结果如下:

  • Chrome: I am inline(没有请求url2)
  • Firefox: I am inline(没有请求url2)
  • IE9:I am inline(请求url2但不执行url2的脚本)
  • IE(6,7,8): I am inline I am dynamic(请求并执行了url2的脚本)

再来看看第二个变种的例子(#3):

<script type="text/javascript" id="external-script" src="url1">
alert('I am inline script');
</script>
<script type="text/javascript">
    document.getElementById('external-script').src='url2';
</script>

其中url1的内容如下:

alert('I am url1');

结果如下:

  • Chrome: I am url1(没有请求url2)
  • Firefox: I am url1(没有请求url2)
  • IE9:I am url1(请求url2但不执行url2的脚本)
  • IE(6,7,8): I am url1 I am dynamic(请求并执行了url2的脚本)

首先这里肯定的是src属性是修改成功的,可以通过看dom的变化看到src已经设置进去了。这个时候我们比对这三个例子,思考几十秒。分析下这三个例子,其实#2和#1是一样的,这里用#2是为了说明#1中的空格、换行符以及回车符会被浏览器认为是内联的脚本。通过比对#2和#3,是不是会让你想到什么?没错,我们第一个会想到的就是:当script标签既有src属性又有内联脚本的时候浏览器该如何处理? , 先来解释这个问题。

一谈到浏览器应该怎样处理,就不得不翻出各种宝典,这次不再是葵花宝典了,而是九阴真经(W3C的HTML4标准),标准中关于script标签的src部分有如下一段话:

If the src attribute is not set, user agents must interpret the contents of the element as the script. If the src has a URI value, user agents must ignore the element's contents and retrieve the script via the URI

上面这段话的意思就是说:如果src没有设置,那么就执行内联脚本,如果src设置了浏览器就必须忽略内敛脚本而要去请求src指定的url的内容

这解释了为什么#3中标准浏览器(甚至IE6,7,8)都没有执行内联脚本(因为src设置了url1)。

搞清楚了这个基础问题之后,接下来问题就定位到了动态修改script的src属性的时候浏览器如何处理? ,从结果来看,标准的浏览器都没有去请求url2(更改src无效),这回IE6,7,8终于犯傻了。当然了,咱们也不能随随便便说人家犯傻,要拿出证据,这个时候继续拿出九阴真经W3C的HTML5标准,其中有这样一句话:

Changing the src, type, charset, async, and defer attributes dynamically has no direct effect; these attribute are only used at specific times described below.

意思就是说:修改src是没用的,对src的处理只会在特定的时候进行(个人猜测就是第一次看到这个属性的时候浏览器会去做相应处理,之后就无视它了)。

好了,这下真相大白了:这解释了为啥#3和#1中除了IE6,7,8之外其他浏览器都没有去请求url2(IE9请求了,但没执行),而且实验发现IE6,7,8对动态修改src都会做请求执行处理。

最后,这个故事至少告诉我们:写script标签的时候千万别手贱打回车。

参考文档:

相关文章

  • 动态修改script标签中的src属性存在的问题

    今天某个同事遇到一个诡异的问题,问题描述如下: 需求:通过脚本动态修改script标签的src来载入一段外部脚本并...

  • 4-1使用jsonp解决跨域

    1、通过静态的script标签的src属性进行跨域请求 2、通过动态的script标签的src属性进行跨域请求

  • 跨域

    JSONP: 原理:动态生成一个script标签(不存在同源策略),在src属性设置要访问的url,并且加上cal...

  • JS 动态插入js文件

    通过修改script标签src属性是无法实现动态加载js文件,并不会向服务器发起新文件的请求 function a...

  • 前端数据请求方式

    一。几种方式 1、 link标签的href属性2、 script标签的src属性3、 img标签的src属性4、 ...

  • 解释 jsonp 的原理,以及为什么不是真正的 ajax?

    JSONP原理: jsonp,即json+padding,动态创建script标签,利用script标签的src属...

  • 面试1

    跨域 jsonp jsonp的原理就是动态滴创建script标签,将script标签的src的url中传入要发给其...

  • JQuery

    引用JQuery在script标签中写出 src 属性,在 src 中写出引用文件的地址 JQuery 的基础写...

  • jsonp原理、$http请求、还有js中作用域、localSt

    1.jsonp原理 动态创建一个script标签,利用script src属性,访问不受限制, 再url后边要跟一...

  • XMLHttpRequest的跨域请求

    XMLHttpRequest的跨域请求 动态添加一个标签,而script标签的src属性是没有跨域的限制的。这样说...

网友评论

      本文标题:动态修改script标签中的src属性存在的问题

      本文链接:https://www.haomeiwen.com/subject/ozhmqttx.html