JavaScript更改iframe src会导致http请求冲突,并且iframe不会重新加载

时间:2018-06-22 19:44:21

标签: javascript html http iframe request

我是Web开发人员的新手,并且对我的问题进行了大量研究,但我仍然感到困惑:

我要实现的目标: 通过URL参数将数据传递到要在iframe文档中使用的iframe src。父页面和iframe位于不同的域。

设置: 我可以拥有一个或多个src =“ www.example.com”的iframe。完全加载DOM后,我尝试更改iframe的src以便附加一些查询参数。 我正在使用纯JS来获取初始iframe src>使用查询参数对其进行合并>将新URL保存在变量中>将iframe src更改为变量中的URL。

问题: 有时,iframe src不会更改-似乎与互联网连接有关。每次刷新javascript都会无法成功更改src,但不会引发任何错误。

我的故障排除: 如果检查页面并转到“网络(Chrome)”,则可以看到有2个针对iframe的HTTP请求:第一个是初始src,第二个是新的src(即使JS未能成功更改它)。 / p>

从这里我遇到了3种情况:

  1. 第一个http请求被取消,第二个http处理结束–一切正常– src更改并传递了数据。

  2. 这两个http请求都保持“待处理”状态-src已更改且数据已传递。

  3. 第一个HTTP请求在第二个HTTP请求开始之前完成。第二个仍处于“待处理”状态-这是问题所在-src不变,即使JS似乎已正确执行,它仍旧保持旧状态。

我了解到,当更改iframe的src时,应该会导致iframe重新加载,从而触发第二个http请求。但是,在情况3发生时,iframe不会重新加载。就像一个http请求“冲突”(不确定它是否是正确的放置方式)。

为什么更改src不能正确地一致地重新加载iframe?

感谢您提出的建议,最佳做法或可行的替代方案。

这是我的代码。我已经发表评论来描述我打算做什么:

paramToPass = ['parma1', 'param2', 'param3']
if (paramToPass) {
    var myIframe = 'myIframeClass'; // define what iframes to find
    var iframes = document.getElementsByClassName(myIframe); // get all iframes from the page with desired class
    var paramStr = paramToPass.join('&'); // create the query parameter string
    var iframesElm;
    for (iframesElm = 0;  iframesElm < iframes.length; iframesElm++) {
        var initialSrc = iframes[iframesElm].getAttribute('src'); // find the initial src of the iframe
        if(initialSrc.indexOf("?") > -1) { // if initialSrc already contains parameters
            var newSrc = initialSrc + '&' + paramStr; // concatonate initial src with parameters
            iframes[iframesElm].src = newSrc; // change the iframe src
            // iframes[iframesElm].setAttribute('src', newSrc); // alternative to change iframe src
        } else { // if initialSrc doesn't contain parameters
            var newSrc = initialSrc + '?' + paramStr; // concatonate initial src with parameters
            iframes[iframesElm].src = newSrc; // change iframe src
            // iframes[iframesElm].setAttribute('src', newSrc); // alternative to change iframe src
        }; 
    };
};

谢谢!

编辑:

新的有效代码。为了更广泛的浏览器兼容性,我为Array.from()forEach()添加了polyfill:

paramToPass = ['parma1', 'param2', 'param3']        
        if (paramToPass.length > 0) {
            var iframes = document.getElementsByClassName(myIframe);
            var paramToPassStr = paramToPass.join('&');
            Array.from(iframes).forEach(function(iframe) {
                iframe.onload = function() { // execute after the iframe is loaded. Prevents http request conflict
                    var initialSrc = iframe.src;
                    var sep = initialSrc.indexOf("?") > -1 ? "&" : "?"; // choose separator based on whether or not params already exist in the initialSrc
                    var newSrc = initialSrc + sep + paramToPassStr;
                    iframe.src = newSrc;
                    console.log('iframe reload');
                    iframe.onload = null; // stops the infinite reload loop
                };
            });
        } else { // paramToPass array is empty, throw error
            console.log('no paramToPassStr to pass found')
        };

1 个答案:

答案 0 :(得分:0)

您可能应该放置代码以将iframe重新加载到其onload处理程序中,以便在iframe首次成功加载后运行。这样就不会有任何冲突。

Array.from(iframes).forEach(iframe => iframe.onload = () => {
    var initialSrc = this.src;
    var sep = initialSrc.indexOf("?") > -1 ? "&" : "?";
    var newSrc = initialSrc + sep + paramStr;
    this.src = newSrc;
    this.onload = null;
});