在表单发布完成对目标执行文件上传后,从 iframe 获取数据

Posted

技术标签:

【中文标题】在表单发布完成对目标执行文件上传后,从 iframe 获取数据【英文标题】:Get the data from an iframe after form post has completed performing a file upload on target for 【发布时间】:2012-10-16 03:54:13 【问题描述】:

我有一个表单,当表单发布到 php 脚本时,它使用 target 属性来定位 iframe。这部分工作正常,但我需要根据 php 脚本将放入 iframe 的几个结果来做一些事情。

我正在考虑做的是当PHP脚本完成发布它时,会回显一些包含各种元素的隐藏输入字段,例如帖子的状态,是否成功以及如果成功,最终结果是什么张贴。

但是,如果我这样做,它会将其放入 iframe,因此主网页将无法访问隐藏的输入字段。

主网页如何能够访问这些隐藏的输入字段,以便主网页可以执行某些操作,即使网页中的 div 显示特定的错误消息或其他内容。

另一件事是,一旦我知道如何从隐藏的输入字段中获取数据,我怎么知道何时可以去获取值。我在想,当表单通过 javascript document.forms["myform"].submit() 代码发布时,我可以做一个 while 循环并检查另一个隐藏输入字段状态是否设置为完成,一旦它说完成,我就可以从隐藏的输入字段。

我不确定我建议的方式是否正确,或者是否正在做我想要实现的目标,或者是否有更好的方法。

更新

我已经尝试了@lanzz 的建议,但似乎没有奏效。以下是我尝试过的。

$("iframe#image_upload_frame").on('load', function()

   var iframeBody = this.contentDocument.body;


   var data = $(iframeBody).find("#imageDirectory");
   alert("data: " + data);
);

以下是 iframe 的定义方式

<iframe id="image_upload_frame" name="image_upload_frame"></iframe>

我在 iframe 内的 php 脚本中回显了一个隐藏的输入字段。

echo '<input type="hidden" id="imageDirectory" value="'.$imageDirectory.'" />';

回显确实有效,因为当我查看 iframe 源时,我可以看到隐藏的输入,但是,警报对话框永远不会显示,好像某些东西不工作一样。谷歌浏览器开发控制台也没有报告错误。

【问题讨论】:

为什么要使用 iframe 来做 Ajax 可以做得更好的事情? @Matthew 抱歉忘记提及,PHP 脚本正在上传用户从表单中选择的文件。这就是为什么我以 iframe 为目标,而不是做一个普通的 ajax 帖子。 @Boardy 你应该看看 Transloadit 。我开始将它用作上传服务,它基本上允许你做同样的事情,但它把它包装在一个 jQuery 插件中,让它变得超级简单。我每月支付 19 美元,我喜欢它。它可以扩展到大文件并将它们转储到我的 S3 帐户中。我可以自己滚动它,但它非常复杂。如果老板符合要求,谁在乎呢。 主页的 URL 和您在iframe 中发帖的 URL 是否位于同一个域中? @Ianzz,是的,他们在同一个域中,它发布到的脚本只是在不同的目录中,但在同一个域中 【参考方案1】:

您可以使用postMessage 在 iframe 与其父级之间进行跨文档通信。

见:

http://viget.com/extend/using-javascript-postmessage-to-talk-to-iframes

http://javascript.info/tutorial/cross-window-messaging-with-postmessage

【讨论】:

【参考方案2】:

由于您在同一个域上运行,因此您的主页的 Javascript 可以轻松访问 &lt;iframe&gt; 的内容(示例使用 jQuery,您可以重写为您计划使用的任何库):

$('iframe#the-id-of-the-iframe').on('load', function() 
    var iframeWin = this.contentWindow;
    var iframeBody = this.contentDocument.body;

    // access global JS vars defined in the iframe:
    var someIframeVariable = iframeWin.globalIframeVariable;

    // or, directly access elements in the iframe:
    var someIframeElement = $(iframeBody).find('#element-id-inside-iframe');
);

【讨论】:

感谢您的帮助,我已尝试过,但似乎没有成功,我已修改订单以显示我的尝试。 您是否在任何地方遇到 JS 错误?尝试在 $('iframe#image_upload_frame).on('load'...) 行之前添加一个 alert($('iframe#image_upload_frame).length) 以查看您是否实际选择了框架。 @Iannzz 当我添加代码时,我会弹出警报消息说 0,我猜这是正确的,因为此时 iframe 是空的。它似乎与加载时因某种原因无法正常工作有关,但没有显示错误【参考方案3】:

如果我理解正确 - 一旦值加载到 iframe 中,您需要父窗口中 iframe 中的值。我会将javascript添加到调用父级并执行函数的iframe中。

在主框架中:

function incomingValue(val) 
   alert(val)

在生成的 iframe 中的某处:

<script type="text/javascript">
 parent.incomingValue("Hello world");
</script>

假设两个帧源共享同一个域,这应该可以工作。

【讨论】:

感谢大家的帮助,感谢@nxtwrld 这个解决方案对我来说很好。【参考方案4】:

不久前,我写了一段代码,使用一些 javascript 和两个 iframe 上传图片。对我来说最重要的是预览图片。也许它会帮助你:

html

<div id='fakebutton' onclick='select_pic()'>Just a button to select a pic</div>
<iframe src='uploadform.php' name'pic_frame'></iframe>
<iframe src='#' name='target_frame'></iframe>

两个 iframe 都是隐藏的。目标框架没有源(或空页面,如果您愿意)。

uploadform.php 包含一个表单:

<form id='upload_form' action='dosomething.php' method='post' enctype='multipart/form-data' target='target_frame' onsubmit=''>
<input id='realfoto' name='realfoto' type='file' onchange='parent.foto_upload(window.frameElement.id)'>
</form>

然后是一些javascript: 首先当用户点击假的时候触发文件浏览器

function select_pic()
   b=window.frames['pic_frame'];
   b.document.upload_form.realfoto.click();
   

然后是实际上传图片的部分,由输入元素中的 onchange() 触发:

function foto_upload(o)
  var b=o;
  o=getElementById(o);
  if(o.contentDocument ) o = o.contentDocument;
  else if(o.contentWindow )o = o.contentWindow;
  elsereturn false;
  if(test_pic(o,b)) //test if it is really a pic
     getObj('foto_tmpdir').value=o.getElementById('tmp_dir').value;
     o.getElementById('doctype_nr').value=b;
     o.fotoform.submit();
     
  else
return false;

在 dosomething.php 中,我对上传的图片执行操作(重命名、调整大小等)。它包含几行javascript:

$a = 'upload was succes';
$b = 'my_image_name';
$c = 'whatever you want to put here';  
?>
  <script type="text/javascript">
  window.top.window.smurf(<?php echo "'$a','$b','$c'" ?>);</script>
  <?php

如果您在 javascripty 中创建一个名为 smurf(a,b,c) 的函数,您可以通过 php 脚本传递您想要的任何内容。对我来说最重要的事情之一是我现在可以将上传图片的文件名传递给 javascript,并使用它来更改 image.src 以进行预览。 希望你可以使用它。

【讨论】:

【参考方案5】:

您的 iframe 源页面应该有一个 javascript 调用函数,而不是隐藏字段。该函数将调用打开器窗口(您的主页),然后执行您想要的任何功能。作为蓝图,请看以下内容:

//in iframe src.php

<?php
if ($something)
?>
<script>
function doSomethingWithOpenerWindow()
opener.document.write('hi);

doSomethingWithOpenerWindow()
</script>
<?php

else
?>
<script>
function doAnotherSomethingWithOpenerWindow()
opener.document.write('hi);

doAnotherSomethingWithOpenerWindow()
</script>  

<?php

?>

【讨论】:

以上是关于在表单发布完成对目标执行文件上传后,从 iframe 获取数据的主要内容,如果未能解决你的问题,请参考以下文章

表单完成提交后执行 javascript

php上传功能怎么实现点击浏览在打开文件之后直接上传?

iframe onload 为目标表单提交触发两次

通过 iframe 上传 Amazon S3

iframe 文件上传在 IE 上不起作用

如何将数据从一个表单发布到另一个 iFrame 表单