使用 Google Gears 和 ASP.NET 或 PHP 上传文件
尝试使用 Google Gears 和 ASP.NET 上传文件...我假设您可以作为 HttpRequest API 接受 blob。
我在页面中有 FileUpload 控件。
<asp:FileUpload runat="server" ID="File1" />
然后是 JavaScript
var file1 = document.getElementById("<%# File1.ClientID %>");
var desktop = google.gears.factory.create('beta.desktop');
file1.onclick = function()
{
desktop.openFiles(openFilesCallback,
{
singleFile: true,
filter: ["image/jpeg"]
}
);
return false;
}
function openFilesCallback(files)
{
if(files.length == 0)
{
alert("No files selected");
}
else
{
// 1MB = 1024 * 1024 bytes
if(files[0].blob.length > (1024 * 1024))
{
alert("File '" + files[0].name + "' is too big to upload");
}
else
{
uploadFile(files[0]);
}
}
}
function uploadFile(file)
{
var up = google.gears.factory.create("beta.httprequest");
up.open("POST", "upload.ashx");
up.send(file.blob);
}
但是,我不确定如何在处理程序中处理它。
public void ProcessRequest (HttpContext ctx)
{
ctx.Response.ContentType = "text/plain";
ctx.Response.Write("Hello World");
ctx.Response.Write(ctx.Request.Files.Count.ToString());
ctx.Response.Write(ctx.Request.Form.Count.ToString());
}
如果我在最后两个语句中的任何一个上设置断点,Files.Count
和 Form.Count
都会返回 0。如果我不这样做,我会在 Firebug 中收到异常: 组件返回失败代码:0x80004001 (NS_ERROR_NOT_IMPLMENTED)
如果我无法使用 POST 通过 Gears 上传,是否可以使用 PUT 来完成?
编辑: PHP 代码也很好(因为我想用两种语言来做)
Trying to upload files using Google Gears and ASP.NET... I assume you can as the HttpRequest API accepts blobs.
I have FileUpload control in the page.
<asp:FileUpload runat="server" ID="File1" />
Then the JavaScript
var file1 = document.getElementById("<%# File1.ClientID %>");
var desktop = google.gears.factory.create('beta.desktop');
file1.onclick = function()
{
desktop.openFiles(openFilesCallback,
{
singleFile: true,
filter: ["image/jpeg"]
}
);
return false;
}
function openFilesCallback(files)
{
if(files.length == 0)
{
alert("No files selected");
}
else
{
// 1MB = 1024 * 1024 bytes
if(files[0].blob.length > (1024 * 1024))
{
alert("File '" + files[0].name + "' is too big to upload");
}
else
{
uploadFile(files[0]);
}
}
}
function uploadFile(file)
{
var up = google.gears.factory.create("beta.httprequest");
up.open("POST", "upload.ashx");
up.send(file.blob);
}
However, I am not sure how to handle it in the handler.
public void ProcessRequest (HttpContext ctx)
{
ctx.Response.ContentType = "text/plain";
ctx.Response.Write("Hello World");
ctx.Response.Write(ctx.Request.Files.Count.ToString());
ctx.Response.Write(ctx.Request.Form.Count.ToString());
}
If I set a breakpoint on either of the last two statements, both Files.Count
and Form.Count
return 0. When I don't I get an exception in Firebug: Component returned failure code: 0x80004001 (NS_ERROR_NOT_IMPLEMENTED)
If I can't use POST to upload via Gears, can it be done using PUT?
Edit:
PHP Code will be fine as well (since I want to do it in both languages)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我认为问题的根源在于,对于 gears,您实际上并没有使用多部分表单/数据上传机制,而是实际上在 POST 请求本身中发送文件数据。
因此,您需要做的实际上是从输入处理程序中读取请求流,并获取数据。您的代码应该如下所示:
当然,是否写入文件或数据库取决于您,以及异常处理和确定是否要创建新文件或追加现有文件等。此外,由于您的代码对文件大小有 1MB 的限制,因此我没有费心去限制缓冲区长度。如果您可能处理非常大的块,您可能需要选择一个较小的缓冲区并从流中分块读取,直到用完数据(这适用于流长度 > int.maxvalue 的情况,所以可能不会可能)。
如果您需要包含原始文件名之类的内容,您有几个选择。一种方法是将 URL 作为查询参数发送(确保其编码正确)。然后你可以从 ctx.Request.QueryString["fileName"] 或类似的地方读取它。
另一种选择是将所需的数据放入客户端的更复杂的对象中,然后使用 JSON 将其全部序列化并将其放入 POST 中。因此,您的客户端代码将类似于:
您需要在服务器端对其进行反序列化,因此您很可能需要 System.Web.Services 中的 DataContractJsonSerializer。另一种选择是 James Newton-King 的 Json.Net 库 (http://james .newtonking.com/pages/json-net.aspx)。
恐怕我在 PHP 方面帮不了什么忙......自从我进入 PHP 领域以来已经有很长、很长、很长的时间了:)
I think the root of your issue is that with gears your not actually using the multipart-form/data upload mechanism, instead your actually sending your file data in the POST request itself.
So what you need to do is actually read the request stream from your input handler, and grab the data. Your code should look something like this:
Of course whether you write to a file or a database is up to you, as well as exception handling and figuring out whether you want to create a new file or append an existing file, etc. Also, since your code had a 1MB limit on file size, I didn't bother to limit the buffer length. If your potentially dealing with very large blocks you may need to pick a smaller buffer and read from the stream in chunks until you run out of data (this would be for the case when your stream length was > int.maxvalue, so probably not likely).
If you need to include things like the name of the original file you have a couple options. One is just to send it with the URL as a query parameter (make sure it's encoded properly). Then you can read it from ctx.Request.QueryString["fileName"] or some such.
Another option would be to put the data you need into a more complex object on the client side, and then use JSON to serialize it all and put it into the POST. So your client code would look something like:
You would need to deserialize it on the server side, so you would most likely need the DataContractJsonSerializer from System.Web.Services. Another option would be the Json.Net library from James Newton-King (http://james.newtonking.com/pages/json-net.aspx).
I'm afraid I can't help much on the PHP side....It's been a long, long, long time since I've been in PHP land :)