【问题标题】:Retrieving response from remote server after uploading a file in iframe在 iframe 中上传文件后从远程服务器检索响应
【发布时间】:2011-05-15 16:31:02
【问题描述】:

我有一个表单,可以将框架中的文件上传到远程服务器。结果在提交 url 服务器返回带有操作结果的 json 数据,我的 iframe 捕获了这些数据。

{'result': 'true' or 'false'}

现在我想检索这个 json 作为 iframe 的回调。我知道我需要 jsonp 来实现这一点,因为它是一个跨站点调用。这是我的函数,带有来自IBM' site 的示例代码:

function fileUploadFunction(){     
    var fileUploadForm = $('#file_upload_form');
    fileUploadForm.attr('action', uploadURL);
    fileUploadForm.submit();
    $('#upload_target').load(function () {
        alert("IFrame loaded");
            $.getJSON(uploadUrl+"&callback=?", function(data) {
                alert("Symbol: " + data.symbol + ", Price: " + data.price);
            });
    });         
};

但是这里很少出现问题。首先 - 我的 uploadUrl 只是 "http://something/" 。我需要它来支持带有$callback= 后缀的呼叫吗?
其次 - 服务器仅作为文件上传的结果给出响应。因此,我需要获取存储在 iframe 中而不是指定 url 中的结果。如何解决?

这是链接。注意表单内隐藏的 iframe。服务器的结果显示在那里。 :

http://ntt.vipserv.org/artifact/


编辑

我之前尝试过:

    $('#upload_target').load(function () {
        var ret = frames['upload_target'].document.getElementsByTagName("body")[0].innerHTML;
        var data = eval("("+ret+")");
    });

但它会引发“权限被拒绝”错误。

【问题讨论】:

标签: javascript iframe cross-domain response jsonp


【解决方案1】:

这很容易用easyXDM 完成,实际上有一篇关于这个确切用例here 的博客文章。

本质上,它的作用是使用跨域消息传递将响应中继到调用文档。

更新: Here is a link 对此进行操作,源代码可在 github 找到,文件前缀为“upload_”。

【讨论】:

  • 所以如果不在服务器端引入一些js,我就无法实现这一点?
  • 不是在服务器端,而是在位于“接收”域的文档上。但是不,你要么需要这个,要么使用 flash/activex 代理等 - easyXDM 更容易。
  • 你用过吗?我不确定我是否正确。我可以在那里看到至少 4 个文件。一个 - 消费者 - 执行上传并将其存储在本地。远程服务器上的第二个 upload_rpc.html。我不确定它是如何与实际上传地址相关联的。然后是本地的“name.html”和远程的“name.html”,我不确定它们的用途。
  • 我是开发者。您可以跳过 name.html ,除非您需要支持一些非常旧的浏览器。 upload_rpc.html 是 XDM 端点,负责将响应转发回来并“托管”作为上传表单目标的 iframe。然后表单发布操作使用parent.foo 将响应传递回原始文档。
  • 所以让我检查一下是否正确 - 我的消费者表单发布到 upload url,指定的目标 iframe 位于 upload_rpc.html。上传后,我将返回我的结果。我还有两个问题 - upload_rpc 中的代码如何知道上传的结果?其次,我是返回 iframe 还是只返回 rpc 响应?我对我需要采取的远程服务器回避措施特别感兴趣,因为我在那里的访问权限非常有限,最好是一次尝试。
【解决方案2】:

Sean 的 easyXDM 建议是一个不错的选择(& 可能应该被标记为正确),但我想建议另一种我没有看到有人使用过的轻量级解决方案。

如果您要发布到另一个域上的隐藏 iframe 并且只需要一个回复(不是双向通信),您可以 使用破坏的 url 将消息从 iframe 传递给父级。这是一个例子:

  1. 父级加载不同域的 iframe

  2. 父轮询myframe.contentWindow.location.href(由于框架位于另一个域上,因此不断收到Permission denied 错误)

  3. iframe 进程,然后重定向到

    http://parentdomain.com/pagethatdoesnotexist?{'result':'ok'}
    
  4. iframe 获得 404,但现在该位置可供父级使用

  5. 父级从 iframe 的 URL 读取消息

【讨论】:

    【解决方案3】:

    一种可能的解决方案是使用纯 js 设置 iframe 的名称。可以从包装父页面读取此名称。

    【讨论】:

    • 和?这有什么用?
    【解决方案4】:

    在我看来,您的代码将请求uploadURL 两次:首先,.submit() 执行 POST 请求以上传文件,结果在 iframe 中显示为网页;其次,.getJSON() 执行 GET 请求,结果在<script> 中作为 javascript 执行。如果您在测试应用时打开 Firebug,您就会意识到这一点。

    由于两个请求是独立的,我不知道.getJSON() 将如何为您提供有关您刚刚使用.submit() 上传的文件的任何信息。

    对于这类跨域通信,我建议使用postMessage;否则,您将需要更改应用程序工作流程以在文件上传后在 iframe 中执行所有操作;例如在 iframe 中执行 <script>alert('Submission accepted');</script>

    用户成功上传文件后,您想做什么?

    【讨论】:

    • 数据库是连接到uploadURL(A) 的域还是用户所在的域(B)?考虑将记录直接在 (A) 的服务器端添加到数据库,因为用户可能会在没有实际将文件上传到 (A) 的情况下向 (B) 发起添加记录请求。
    • db 位于本地域 (B) 并在 (A) 上传。这就是为什么我在成功上传后从服务器得到响应的原因。响应显示在 iframe 中。所以我想把它读出来,如果 'response' == 'true' 向我的数据库添加一个新实例。
    • 那么您应该使用postMessage 将信息从iframe 中的上传结果传递给其父级。您可能希望在 (a) 和 (b) 之间建立一些共享秘密,以确保添加记录请求真正合法。
    • 那么我应该在哪里放置带有 pm 的脚本,在 iframe 中,在本地上传服务器上?
    • 是的。从域 (b) 上的 iframe 发送消息,在域 (a) 上的父页面侦听消息,将 db 数据与消息一起发送到 (a);使用 (a) 和 (b) 之间的共享密钥检查消息。
    【解决方案5】:

    根本不要使用 .html()。

    我用过

    jQuery('.someElement')
    

    它对我有用。您可以将结果保存在变量中并将其插入新元素中

    例如

    var = jQuery('.someElement');
    jQuery('.newElement').html(var);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-05-23
      • 2015-07-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-08
      • 2013-06-20
      相关资源
      最近更新 更多