【问题标题】:How should I write a web API that receives a file?我应该如何编写一个接收文件的 Web API?
【发布时间】:2012-10-15 06:13:55
【问题描述】:

我正在尝试创建一个 Web API,允许某人(最好是程序)提交一个大型二进制文件并接收该文件的 ID 作为回报。我有一些带有表单 (method="POST") 和 <input type="file" ...> 元素的 HTML,可以使用标准的 multipart/form-data MIME 类型将文件提交给一些 PHP 代码。 PHP 生成 ID 并将其作为结果打印出来。因为 PHP 只是打印 ID,而不是重定向到另一个 HTML 页面或生成 HTML 本身,所以它不是很漂亮,但希望对于程序化文件提交 API 的预期用例来说已经足够了。

到目前为止,一切都很好。当我想让客户端代码捕获返回的 ID 并使用它调用其他 API 时,这会变得很棘手。如果客户端是带有 JavaScript 的网页,似乎客户端应该使用XMLHttpRequest,但我不清楚如何让该对象使用用户通过文件输入控件选择的文件。

我希望同一个 API 既可以用于手动操作的 Web 表单(便于 UI 和测试),也可以用于纯编程调用(如 JavaScript、curl/libcurl 等)。我不希望 PHP 使用查询字符串中的 ID 重定向到另一个页面,并且我不希望直接返回 HTML。我只想要一个简单的文件,ID out API。

由于事实证明这很困难,我怀疑我做事的方式不对。我对替代设计持开放态度,但我更愿意让事情尽可能简单。我找到了一个有点 similar question,但它太以 Java 为中心,并不能完全解决我的问题。

【问题讨论】:

  • 您的问题是“如何使用 JavaScript 上传用户选择的文件并捕获返回的文档?”?这似乎是您遇到的唯一问题,但您担心的其他问题似乎与服务器端的设计有关。
  • 或多或少。该文件可以由用户选择(如在表单中),或以编程方式提供(如从脚本中)。返回的文档实际上只是一个 ID,具有任何有意义的包装,并且可供客户端 JavaScript 使用。我担心的是服务器端代码与我的客户端用例兼容。我很乐意调整其中一个来解决问题。

标签: php javascript web-services api file-upload


【解决方案1】:

我不得不做类似的事情,我最终做的是将表单提交到隐藏的 iframe。然后可以简单地在 iframe onload 处理程序中检索来自 php 的响应。

其实我用的代码如下:

    $('submitdestination').onload=function(){
        var appID=this.contentDocument.body.children[0].innerHTML;
        //did something with appID
        new mBox.Notice({type: 'ok',delayClose: 1000,content: 'Data saved.',position: {y: 'bottom',x: 'right'}});//displayed message
    }
    $('cvdetails').submit();

注意:submitdestination 是我的 iframe。 cvdetails 是我的表格。表单的目标设置为submitdestination。另外,我正在使用 Mootools,以防有人注意到我的美元参数中缺少散列。

这是我使用的 HTML 的精简版(尽管 iframe 没有改变):

<form id="cvdetails" name="cvdetails" action="scripts/upload.php" method="post" enctype="multipart/form-data" target="submitdestination" autocomplete="off">
    <button type="button" id="save" class="mainbutton">Save</button>
</form>
<iframe id="submitdestination" name="submitdestination" style="display:none" ></iframe>

保存按钮有一个点击处理程序,可以简化为:

$('save').addEvent('click',function(evt){evt.stop();$('cvdetails').submit();})

【讨论】:

  • 当我研究这个时,我看到提到了隐藏的 iframe 方法,但我没想到要在 onload 处理程序中捕获响应。您能否链接到或发布一些示例代码?我认为人们会从一起看到这一切中受益。
  • 我已经发布了代码。我的情况比我想象的更类似于你的情况,尽管我在响应 html 的 body 标记中输出了一两个元素。第一个孩子包含申请人的ID(这是用于生成公司格式的单词简历)
  • 很抱歉再次打扰您,@Asad,但您能否发布隐藏 iframe 的 HTML 和提交给它的表单?我很想一次看到所有的组件。
  • 我无法发布由 php 生成的确切 HTML,但我在上面的答案中添加了一个简化版本。我想为此做一个小提琴,但它同时涉及客户端和服务器端脚本,这使事情变得复杂。
  • 感谢@Asad 提供的示例。你真的帮我解决了问题。享受25分。 :)
【解决方案2】:

感谢@Asad 的帮助,我能够按照我想要的方式进行工作。综上所述,我基本上有以下代码:

<html>
    <head>
        <script type="text/javascript">

window.onload = function(){
    setUploadID(-1);
    document.getElementById('hidden_iframe').onload = captureUploadID;
}

function setUploadID(id)
{
    document.getElementById('upload_id').innerHTML = id;
}

function captureUploadID()
{
    var upload_id = this.contentDocument.body.childNodes[0].textContent;
    setUploadID(upload_id);
}
        </script>
    </head>
    <body>
        <form action="upload.php" enctype="multipart/form-data" method="POST" target="hidden_iframe">
            File: <input type="file" name="media" /><br>
            <input type="submit" value="Upload" />
        </form>
        <br>
        Upload ID: <span id="upload_id"></span>
        <iframe id="hidden_iframe" style="display: none;"></iframe>
    </body>
</html>

【讨论】:

    猜你喜欢
    • 2011-05-18
    • 1970-01-01
    • 1970-01-01
    • 2020-04-06
    • 1970-01-01
    • 2011-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多