我应该如何编写接收文件的Web API?

时间:2012-10-15 06:13:56

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

我正在尝试创建一个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为中心,并没有完全解决我的问题。

2 个答案:

答案 0 :(得分: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();})

答案 1 :(得分:0)

感谢@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>