使用FileSystem API创建文件上传至S3时内容为路径的问题排查
问题:FileSystem API创建的文件上传到S3后内容是文件路径而非实际内容
这个问题我一眼就看出来了——你上传的不是文件的实际内容,而是直接把文件路径的字符串传给了S3的Body参数,难怪S3里的文件内容是路径文本!咱们一步步拆解问题和解决方法:
核心问题分析
- 错误的上传内容类型:在
addPhoto函数里,你把file_path(这是个字符串)直接赋值给了file,然后传给S3的Body。S3会原封不动地把这个字符串当成文件内容上传,自然不会是你写入的JSON数据。 - 异步时机错误:你在
fileWriter.write(blob)之后立刻调用addPhoto,但文件写入是异步操作——这时候文件可能还没写完,就算你拿到了路径,也读不到正确的内容。 - 路径赋值时机不对:
FILE_PATH = FILE_PATH + fileEntry.fullPath写在fileEntry.createWriter的回调外面,这时候fileEntry.fullPath还没被正确初始化,拿到的路径可能是不完整的。
修复方案
我们需要等文件写入完成后,从fileEntry中读取实际的文件Blob,再传给S3:
- 把上传逻辑移到写入完成的回调里,确保文件写完之后再处理上传。
- 从
fileEntry获取文件内容,用fileEntry.file()方法获取File对象,再把这个File对象传给S3的Body。 - 修正路径赋值的位置(可选,其实这里路径已经不是必需的了)。
修改后的代码示例
var FILE_PATH = 'filesystem:http://localhost:5000/temporary'; function onInitFs(fs) { fs.root.getFile('log.json', {"create": true}, function(fileEntry) { fileEntry.createWriter(function(fileWriter) { fileWriter.onwriteend = function(e) { console.log('Write completed.'); // 等文件写入完成后,再读取文件并上传 fileEntry.file(function(file) { addPhoto('hero', file); // 直接传File对象,不是路径 }, errorHandler); }; fileWriter.onerror = function(e) { console.log('Write failed: ' + e.toString()); }; var sukshi_dict = { "sfds": "sdfse" }; var sukshi_json = JSON.stringify(sukshi_dict); var blob = new Blob([sukshi_json], {"type": "application/json"}); fileWriter.write(blob); }, errorHandler); FILE_PATH = FILE_PATH + fileEntry.fullPath; console.log(FILE_PATH); }, errorHandler); } window.requestFileSystem(window.TEMPORARY, 5*1024*1024 /*5MB*/, onInitFs, errorHandler); function addPhoto(albumName, file) { if (!file) { return alert('Please choose a file to upload first.'); } var fileName = file.name; // 直接用File对象的name属性,不用自己截取路径 console.log(fileName); var albumPhotosKey = encodeURIComponent(albumName) + '/'; var photoKey = albumPhotosKey + fileName; s3.upload({ "Key": photoKey, "Body": file, // 这里传File对象,S3会读取它的内容 "ACL": 'public-read' }, function(err, data) { if (err) { return alert('There was an error uploading your photo: ', err.message); } alert('Successfully uploaded photo.'); }); }
关键修改点说明
- 把
addPhoto的调用移到了fileWriter.onwriteend里,并且通过fileEntry.file()获取了实际的File对象,而不是传路径字符串。 addPhoto函数现在接收File对象作为参数,直接用file.name获取文件名,不用手动截取路径,更可靠。- S3的
Body参数现在接收的是File/Blob对象,S3会自动读取它的内容并上传,而不是把字符串当内容。
这样修改后,上传到S3的文件就会是你写入的JSON内容了!
内容的提问来源于stack exchange,提问作者Manoj vardhan reddy
相关产品推荐
相关产品推荐

