gpt4 book ai didi

带有 POST 数据的 Javascript XMLHttpRequest 上传文件

转载 作者:行者123 更新时间:2023-11-29 23:27:12 26 4
gpt4 key购买 nike

我正在尝试使用拖放在 JavaScript 中创建小型上传。我已经写了代码,但是它似乎不起作用。目前网站的工作方式,上传脚本必须向网站提供信息,例如 PHPSESSID、服务器处理请求的附加数据和文件本身。如果用户删除了多个文件,脚本应该将它们一一上传。然而,目前我什至无法让 JavaScript 上传一个文件。在调试工具中查看时,服务器正在响应网站本身,而不是用于文件上传的响应。

在旧版本代码中使用现有表单上传文件时,我注意到在发送文件内容之前来自网络浏览器的请求如下所示:

Content-Disposition: form-data; name="file"; filename="file.txt"
Content-Type: text/plain

然而,当使用我使用过的脚本发送时,我只看到了这个:

Content-Disposition: form-data; name="file"

但是我不确定代码有什么问题,也无法找到任何有助于解决此问题的信息。

我不想使用额外的库,例如 JQuery 或任何类似的库

Javascript 代码:

function drop(e){
e.preventDefault();
if(e.dataTransfer.items){
for(var i=0; i < e.dataTransfer.items.length; i++){
var reader = new FileReader();
var req = new XMLHttpRequest();
var f = e.dataTransfer.files[i]
req.onprogress = function(e){
if (e.lengthComputable){
console.log("progress: " + e.loaded / e.total);
}
}
req.open("POST", document.location, true);
req.setRequestHeader("Content-Type", "application/octet-stream");
reader.onload = function(e){
var fd = new FormData();
fd.append("PHPSESSID", document.cookie.split("=")[1]);
fd.append("request", JSON.stringify({"command":"upload", "path":path + f.name, "path-type":pathtype}))
fd.append("file", e.target.result);
req.send(fd);
}
reader.readAsBinaryString(e.dataTransfer.items[i].getAsFile());
}
}else{
for(var i=0; i < e.dataTransfer.files.length; i++){
console.log(e.dataTransfer.files[i]);
}
}
}

负责上传的 PHP 代码:

if(isset($_POST['request'])){
$request = json_decode($_POST['request'], true);
if($request['command'] == "upload"){
if(isset($request['path']) && isset($request['path-type'])){
$path = "";
if($request['path-type'] === "private"){
$path = truepath($private_dir . $request['path']);
if(!(substr($path, 0, strlen($private_dir)) === $private_dir)){
die();
}
}elseif($request['path-type'] === "public"){
$path = truepath($public_dir . $request['path']);
if(!(substr($path, 0, strlen($public_dir)) === $public_dir)){
die();
}
}else{
die();
}
move_uploaded_file($_FILES["file"]["tmp_name"], $path);
die();
}
}
die();
}

最佳答案

经过几天的试验,我发现服务器端失败的原因是代码未设置 $_POST$_FILES

代码失败的原因有多种,都是JavaScript端造成的。

需要改变的地方:

  1. FileReader 完全没有必要。
  2. req.setRequestHeader("Content-Type", "application/octet-stream"); 不正确,因为它应该是“multipart/form-data”。除此之外,不应设置它,因为它会破坏内容类型 header 。这是因为上传文件时,Content-Type header 还包含由浏览器生成的边界。当您设置 Content-Type 时,您将覆盖浏览器为文件上传生成的任何内容。 I was able to find this out thanks to this answer.

PHP 端的代码(令人惊讶地)正确。 JavaScript 的最新代码是:

function drop(e){
e.preventDefault();
if(e.dataTransfer.files){
for(var i=0; i < e.dataTransfer.files.length; i++){
var req = new XMLHttpRequest();
var f = e.dataTransfer.files[i]
req.onprogress = function(e){
if (e.lengthComputable){
console.log("progress: " + e.loaded / e.total);
}
}
req.open("POST", document.location, true);
req.overrideMimeType('application/octet-stream')
var fd = new FormData();
fd.append("PHPSESSID", document.cookie.split("=")[1]);
fd.append("request", JSON.stringify({"command":"upload", "path":path + f.name, "path-type":pathtype}))
fd.append("file", f);
req.send(fd);
}
}
}

关于带有 POST 数据的 Javascript XMLHttpRequest 上传文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48689430/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com