简体   繁体   English

在javascript中引用文件上传

[英]Referencing a file upload in javascript

I think I know that this is a 'no' but I'm going to ask anyway: 我想我知道这是“不”,但我还是要问:

I have an SPA (react) and the user sends in items to be repaired. 我有一个SPA(反应),并且用户发送了要维修的物品。 I'm trying to get it so that the user can take a picture of their item for identification. 我正在尝试获取它,以便用户可以为其商品拍照以进行识别。

I'm hoping to create a collection of data to manipulate throughout the app, like so: 我希望创建一个数据集合以在整个应用程序中进行操作,如下所示:

const repairs = [
  {name: 'item1', imgURL: '<reference to local file in some way>'},
  {name: 'item2', imgURL: '<reference to other local file in some way>'}
];

To get the data I'm going to use a form (obviously!). 为了获得数据,我将使用一个表单(很明显!)。 In effect the form where the user inputs the data should use a file upload, right?! 实际上,用户输入数据的形式应该使用文件上传,对吗? And be something like this: 并且是这样的:

<form id="myForm">
    <input type="file" name="avatar" id="avatar">
    <input type="text" name="name" id="name">
    <input type="submit">
</form>

Using the FormData API, I can get a reference to the file and show it on that page. 使用FormData API,我可以获得对该文件的引用,并在该页面上显示它。 The problem really is about persisting that reference. 问题实际上是关于坚持引用。

On another page I may want a list of repair items, like so: 在另一页上,我可能需要维修项目列表,如下所示:

<li className="repair">
  <img src={repair.imgURL} alt={repair.name} />
</li>

but the question is how to persist and reference the file path... 但问题是如何保留并引用文件路径...

EDIT: Sorry, to be clearer, I know about localstorage. 编辑:很抱歉,更清楚地说,我知道本地存储。 My issue was getting the reference to the file. 我的问题是获取对该文件的引用。 When you get the FormData object, the file data looks like this: 当您获取FormData对象时,文件数据如下所示:

File {
  name: "BB_map_pin_black.png",
  lastModified: 1491366453000,
  lastModifiedDate: Wed Apr 05 2017 05:27:33 GMT+0100 (BST), 
  webkitRelativePath: "", size: 1516…
}

...which isn't enough to reference it by on another page. ...不足以在另一页上引用它。 I need a file path or for the system to hold some kind of reference to the location of that file because the file listed in the object above is in my downloads folder, not the folder my project is currently in... 我需要一个文件路径或系统保留对该文件位置的某种引用,因为上面对象中列出的文件位于我的下载文件夹中,而不是我的项目当前位于的文件夹...

You may want to look into localStorage to store the filePath 您可能需要查看localStorage来存储filePath

The localStorage property allows you to access a local Storage object. localStorage属性允许您访问本地存储对象。 localStorage is similar to sessionStorage. localStorage与sessionStorage类似。 The only difference is that, while data stored in localStorage has no expiration time, data stored in sessionStorage gets cleared when the browsing session ends—that is, when the browser is closed. 唯一的区别是,尽管存储在localStorage中的数据没有到期时间,但是在浏览会话结束时(即,在关闭浏览器时),存储在sessionStorage中的数据将被清除。

Store path 存放路径

localStorage.setItem('filePath', 'YOUR_PATH');

Read Path 读取路径

var file_path = localStorage.getItem('YOUR_PATH');

You can also store objects by stringifying it. 您也可以通过对对象进行字符串化存储。

localStorage.setItem('formData', JSON.stringify(YOUR_FORM_DATA_OBJ));

when reading parse to object 在读取解析为对象时

var YOUR_FORM_DATA_OBJ = JSON.parse(localStorage.getItem('formData'));

UPDATE 更新

Checkout this fiddle 查看这个小提琴

Your cannot read path to the file due to security issue 由于安全性问题,您无法读取文件的路径

but you can convert your file to blob dataURL and save it in localStrorage 但您可以将文件转换为Blob dataURL并将其保存在localStrorage中

In the fiddle above I have used image to store in localstorage and show them later. 在上面的小提琴中,我使用图像存储在本地存储中,并在以后显示它们。

STORING FILE 存储文件

avatar = input.files[0];    //Read your input file here
var reader  = new FileReader();   //create a FileReader Object 

reader.addEventListener("load", function () { // A listener to read the file as blob
  var data = reader.result; // Your blob data

  // Saving the blob data to localStorage
  localStorage.setItem('fileData', // Key and object storing name and blob data of file
                        JSON.stringify({name:avatar.name,data:data})); 
  }, false);

  if (avatar) {
    // reading file to get blob, this will call the load method above
    reader.readAsDataURL(avatar);
  }

READING FILE 读取文件

var fileData = localStorage.getItem('fileData');  // getting data from local storage

   if(fileData) {
    fileData = JSON.parse(fileData);      // parsing local storage data
    avatar=dataURLtoFile(fileData.data,"filename"); //converting dataURL to file

}

/*Function to convert blob dataURL and returns a file object
  Takes a dataURL (data:image/png;base64,sadasd...) and filename
  and returns a file object
*/
function dataURLtoFile(dataurl, filename) {
    var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],
        bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
    while(n--){
        u8arr[n] = bstr.charCodeAt(n);
    }
    return new File([u8arr], filename, {type:mime});
}

FULL JS 全JS

window.input = $('#myForm').find('#avatar')[0];
window.preview = $('#show');
window.avatar;

function dataURLtoFile(dataurl, filename) {
    var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],
        bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
    while(n--){
        u8arr[n] = bstr.charCodeAt(n);
    }
    return new File([u8arr], filename, {type:mime});
}

function changeFile() {

  avatar = input.files[0];    //Read your input file here
  var reader  = new FileReader();   //create a FileReader Object

  var path = URL.createObjectURL(avatar); //Create URL to show current image
  preview[0].src=path;  // set url of blob to image src (just to preview current image)

  reader.addEventListener("load", function () { // A listener to read the file as blob

  var data = reader.result; // Your blob data

  // Saving the blob data to localStorage
  localStorage.setItem('fileData', // Key to store
                        JSON.stringify({name:avatar.name,data:data})); // an object storing name and blob data of file
  }, false);

  if (avatar) {
    reader.readAsDataURL(avatar);  // reading file to get blob, this will call the load method above
  }

}

input.addEventListener('change', changeFile); // adding change listener to input 

window.init = function(){ // called on page load

   var fileData = localStorage.getItem('fileData');  // getting data from local storage

   if(fileData) {
    fileData = JSON.parse(fileData);      // parsing local storage data
    avatar=dataURLtoFile(fileData.data,"filename"); converting dataURL to file
    var path = URL.createObjectURL(avatar);// getting a url to show the image
    preview[0].src=path; // setting url to image
   }


}

init();

Files don't have a JS-accessible path property because that can reveal usernames and other confidential/personal information to the site's operators. 文件没有JS可访问的路径属性,因为它可以向站点的操作员显示用户名和其他机密/个人信息。 Also, once you reload a page, you've lost the file reference; 另外,重新加载页面后,您还会丢失文件引用; it won't help to have the full path because you still won't have a reference to the File object, and you can't pre-populate an <input type=file> . 它没有完整路径,因为您仍然没有对File对象的引用,并且您无法预先填充<input type=file> You can save the contents of the file, and the name , but not the path . 您可以保存文件的内容名称 ,但不能保存path If you upload the file to your server, you can have your server return a url that can be linked from any page. 如果将文件上传到服务器,则可以让服务器返回可以从任何页面链接的URL。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM