模拟 type="file"使用 XMLHttpRequest 输入

发布于 2024-11-07 15:44:24 字数 2228 浏览 0 评论 0 原文

我正在测试我在网络上找到的这段代码。我还尝试了在 this 答案中找到的代码,但似乎没有任何内容按照我想要的方式工作。这是我的 javascript:

function fileUpload(url, fileData, fileName) 
{
   var fileSize = fileData.length,
     boundary = "---------------------------7da24f2e50046",
     xhr = new XMLHttpRequest();

   xhr.open("POST", url, true);
          // simulate a file MIME POST request.
   xhr.setRequestHeader("Content-Type", "multipart/form-data, boundary="+boundary);
   xhr.setRequestHeader("Content-Length", fileSize);

   var body = "--" + boundary + "\r\n";
   body += "Content-Disposition: form-data; name='file'; filename='" + fileName + "'\r\n";
   body += "Content-Type: application/octet-stream\r\n\r\n";
   body += fileData + "\r\n";
   body += "--" + boundary + "--";
   alert(body);
    xhr.onreadystatechange = function ()
    {
        if (xhr.readyState == 4 && xhr.status == 200)
        {
            alert(xhr.responseText);
        }
    }

   xhr.send(body);
   return true;
}

function send()
{
    fileUpload("receive.php", "abcdefg", "foo.txt");
}

这是我的“receive.php”文件:

<html>
<head>
</head>
<body>
<?php
    foreach ($_POST as $var => $value) echo "$var = $value<br>n"; 
?>
</body>
</html>

我得到了“receive.php”HTML,但没有任何 echoed。但如果我实际上从 HTML 表单发送文件,它会回显文件名。

我还尝试使用 Fiddler2 拦截一些真实的文件上传,以查看 POST 消息是什么,但我似乎无法在消息中的任何位置找到文件内容。我认为该文件的内容可能以某种方式进行了编码,因此我尝试发送一个相当大的文件(大约 2MB),看看是否可以在发送的消息中的任何位置找到一些大数据块,但我没有。我只看到标题和文件名。

我错过了什么吗?

编辑 我真的觉得我错过了一些明显的东西。下面是我上传真实文件时 Fiddler2 的截图:

fiddler截屏

内容长度是字符串的大小底部,不包含文件内容,仅包含文件名。我正在使用的函数以及执行我想要执行的操作的每个 javascript 代码都将内容长度设置为一个字符串,其中包括文件的内容、边界和其他信息,如您在上面的代码中看到的那样。所以我的功能是创建一个 POST 消息,该消息的结构与 Fiddler 向我显示的 POST 消息不同。

文件内容到底在哪里。另一个奇怪的事情是,当我从 IE 发送 2MB 大小的文件时,页面几乎立即导航到接收文件的页面,就好像没有真正发送任何内容一样。我很困惑。

编辑2我搞砸了。我用来测试上传的表格有问题。我正在使用另一种形式,现在我可以在 Fiddler 中看到文件内容。我想可能是因为我错过了“enctype='multipart/form-data'”所以现在我可以明白为什么我的javascript不起作用了。当我找到解决方案时我会通知你。

I'm testing this code that I found somewhere on the web. I also tried code that I found in this answer, but nothing seems to be working as I want it to. Here is my javascript:

function fileUpload(url, fileData, fileName) 
{
   var fileSize = fileData.length,
     boundary = "---------------------------7da24f2e50046",
     xhr = new XMLHttpRequest();

   xhr.open("POST", url, true);
          // simulate a file MIME POST request.
   xhr.setRequestHeader("Content-Type", "multipart/form-data, boundary="+boundary);
   xhr.setRequestHeader("Content-Length", fileSize);

   var body = "--" + boundary + "\r\n";
   body += "Content-Disposition: form-data; name='file'; filename='" + fileName + "'\r\n";
   body += "Content-Type: application/octet-stream\r\n\r\n";
   body += fileData + "\r\n";
   body += "--" + boundary + "--";
   alert(body);
    xhr.onreadystatechange = function ()
    {
        if (xhr.readyState == 4 && xhr.status == 200)
        {
            alert(xhr.responseText);
        }
    }

   xhr.send(body);
   return true;
}

function send()
{
    fileUpload("receive.php", "abcdefg", "foo.txt");
}

And this is my "receive.php" file:

<html>
<head>
</head>
<body>
<?php
    foreach ($_POST as $var => $value) echo "$var = $value<br>n"; 
?>
</body>
</html>

I'm getting the "receive.php" HTML back but without anything being echoed. But if I actually send a file from an HTML form it echos the file name.

I'm also trying to use Fiddler2 to intercept some real file uploads to see what the POST message is, but I can't seem to find the file content anywhere in the message. I figured the file's content might be encoded somehow so I tried sending a pretty large file, about 2MB, to see if I can find some big chunk of data anywhere in the message being sent, but I didn't. I just see the header and the file name.

Am I missing something?

Edit I really feel I'm missing something obvious. Here is a screenshot of Fiddler2 when I upload a real file:

fiddler screenshot

The content length is the size of the string at the bottom, which doesn't include the file's content but just the file name. The function I'm using and every javascript code that does what I'm trying to do set the content length to a string that includes the file's content and the boundary and other information as you can see in my code above. So my function is creating a POST message that has a different structure that the POST message that Fiddler is showing me.

And where in the world is the file content. Another weird thing is that when I send a 2MB size file from IE, the page navigates to the page that receives the file almost instantaneously, as if nothing is being really sent. I'm very confused.

Edit2 I messed up. There was something wrong with the FORM I was using to test uploads. I'm using another form and now I can see the file contents in Fiddler. I think is probably because I was missing the "enctype='multipart/form-data'" So now I can see why is my javascript not working. I'll let you know when I find a solution.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

此生挚爱伱 2024-11-14 15:44:24

JavaScript 无法读取硬盘上的文件内容。鉴于您的示例,无法填充 fileData 变量。

Javascript cannot read content of files on your hard disk. Given your example, there is no way to populate the fileData variable.

も让我眼熟你 2024-11-14 15:44:24

这有效:

function SendFile(url, fileName, fileContent) 
{
    xhr = new XMLHttpRequest();

    xhr.open("POST", url, true);
    var boundary = '---------------------------7da24f2e50046';
    xhr.setRequestHeader("Content-Type", "multipart/form-data; boundary=" + boundary);

    var body = "" +     
        '--' + boundary + '\r\n' + 
        'Content-Disposition: form-data; name="file[]"; filename="' + fileName + '"' + '\r\n' + 
        'Content-Type: text/plain' + '\r\n' + 
        '' + '\r\n' + 
        fileContent + '\r\n' + 
        '--' + boundary + '--' + 
        ''; 

    xhr.onreadystatechange = function ()
    {
        if (xhr.readyState == 4 && xhr.status == 200)
        {
            alert(xhr.responseText);
        }
    }

   xhr.send(body);
   return true;
}

This worked:

function SendFile(url, fileName, fileContent) 
{
    xhr = new XMLHttpRequest();

    xhr.open("POST", url, true);
    var boundary = '---------------------------7da24f2e50046';
    xhr.setRequestHeader("Content-Type", "multipart/form-data; boundary=" + boundary);

    var body = "" +     
        '--' + boundary + '\r\n' + 
        'Content-Disposition: form-data; name="file[]"; filename="' + fileName + '"' + '\r\n' + 
        'Content-Type: text/plain' + '\r\n' + 
        '' + '\r\n' + 
        fileContent + '\r\n' + 
        '--' + boundary + '--' + 
        ''; 

    xhr.onreadystatechange = function ()
    {
        if (xhr.readyState == 4 && xhr.status == 200)
        {
            alert(xhr.responseText);
        }
    }

   xhr.send(body);
   return true;
}
生死何惧 2024-11-14 15:44:24

您无法使用 ajax 请求发送文件数据。大多数框架都通过创建一个隐藏的 iframe,然后将该 iframe 发布到您的服务器来掩盖这一点。对于客户端来说,它看起来像ajax;然而,这只是原始问题的解决方法。您将需要执行类似的操作才能获得效果;找到您选择的 ajax 文件上传库并使用它,或者编写您自己的 iframe 发布解决方案。

You can't send file data with an ajax request. Most every framework out there masks this by creating a hidden iframe and then posting that iframe to your server. To the client, it looks like ajax; however, it's just a workaround to the original problem. You will need to do something similar to get the effect; find the ajax file upload library of your choice and use that, or write your own iframe posting solution.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文