我是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种情况:
第一个http请求被取消,第二个http处理结束–一切正常– src更改并传递了数据。
这两个http请求都保持“待处理”状态-src已更改且数据已传递。
第一个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')
};
答案 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;
});