js realizes the function of image upload and deeply understands the principle of image upload

Posted by fri3ndly on Fri, 06 Dec 2019 10:50:04 +0100

js realizes the function of uploading pictures. The effect is to see the pictures first to suppress the shock


Picture upload.gif

Principle:

Structure part: input tag

You may not have noticed that the input tag has the same effect.
1. The type attribute is file
2.accept is the file format allowed to be selected (if it is a picture, no other format will appear in the selection box),
3. The parameter of the onchange callback function is the file object data we selected.
As follows:

<input  type='file'  accept='image/*'  onChange={this.handleSelectFile.bind(this,this.state.uploadUrl)} />

js part: ajax request

By instantiating the XMLHttpRequest object, the ajax request is initiated, the progress and readyState values are monitored, the back-end return values are obtained, and the upload is completed.

Be careful:

1. The image upload function can separate the selection process from the upload process. For example, if you select a picture, you can preview the picture, select and preview it multiple times, and finally confirm the upload!

2. You can modify the code by yourself, which can be applied to upload videos or other files!

github:https://github.com/Amy-Tong126/uploadImageDemo
The UI part of the image upload function is based on antd. If you do not use antd, you can replace it in the corresponding location.
The specific code is as follows:

JSX:

import logo from './logo.svg';
import './App.css';
import { message,Modal,Icon,Progress } from 'antd';
import uploadFunction from "./js/uploadFunction";


class App extends Component {
    constructor(props){
        super(props);
        this.state={
            file:{},//Save file object content
            src:"",//url to save the picture
            progress:0,//Upload progress
            uploadUrl:"http://192.168.1.20:13003/fileDetail/upImg/1/3139 ", / / upload address
        }
    }
  /*
    Click event triggering input when clicking upload
  */
  clickUploadBtn(){
      this.refs.uploadInput.click();
  }
  /*
  * Select pictures to upload
  * */
  handleSelectFile(uploadUrl,e){
      const file = e.target.files[0];
      if (!file) {
          return;
      }
      let src;
      // Match string of type beginning with image /
      if (file.type==="image/png"||file.type==="image/jpeg") {
          src = URL.createObjectURL(file);
      }else{
          message.error("Image upload only supported JPG/PNG format,Please upload again!");
          return;
      }
      if (file.size/1024/1024>5) {
          message.error("Image upload size should not exceed 5 MB,Please upload again!");
          return;
      }
      this.setState({
          file:file,
          src:src
      });
      this.startUpload(uploadUrl,file);
  }
  /*
  * Start uploading pictures
  * */
  startUpload(uploadUrl,file){
      let this_=this;
      /*
      * Call the encapsulation method of upload picture
      * */
      uploadFunction.uploadForImage(
          uploadUrl,
          file,
          function (progress,response) {//Callback function processing progress and back-end return value
              this_.setState({
                  progress:progress
              });
              if (response&&response.code === 200) {
                  message.success("Upload succeeded!");
              }else if (response && response.code !== 200) {
                  message.error(response.msg)
              }
          },
          localStorage.getItem("access_token"));
  }

  render() {
    return (
      <div className="App">
          <div style={{float:"left"}}>
              {this.state.src?
                  <div className="imgBox">
                      <img src={this.state.src} alt=""/>
                      {this.state.progress===100?null:
                          <div className="mask">
                              <div className="fileName">
                                  {this.state.file.name}
                              </div>
                              <div className="progress">
                                  <Progress
                                      percent={this.state.progress}
                                      size="small"
                                      status="active"
                                      showInfo={false}
                                      strokeColor="#31c060"
                                      strokeWidth={3}
                                  />
                              </div>
                          </div>
                      }
                  </div>
                  :
                  <div
                      className="uploadBox"
                      onClick={this.clickUploadBtn.bind(this)}
                  >
                      <Icon type="plus" style={{lineHeight:"150px",fontSize:"40px",color:"#999"}}/>
                  </div>
              }
              <input
                  ref="uploadInput"
                  type='file'
                  accept='image/*'
                  style={{width:"100px",border:"none",visibility:"hidden"}}
                  onChange={this.handleSelectFile.bind(this,this.state.uploadUrl)}
              />
          </div>

      </div>
    );
  }
}

export default App;

The uploadFunction function introduced above is as follows:

function uploadForImage(url,data,callback,token) {//data is a file object
   let xhr = new XMLHttpRequest();
   let form = new FormData();
   form.append('file', data);
   function uploadProgress(e) {
       if (e.lengthComputable) {
           let progress = Math.round((e.loaded / e.total) * 100);
           callback(progress);
       }
   }
   /*
   * Listen for the progress of the request and pass in the progress parameter in the callback*/
   xhr.upload.addEventListener('progress',uploadProgress, false);  // The third parameter is useCapture? Use event capture / bubbling
   /*
   * Listen for the change of readyState, and call back the response returned by the backend when finished
   * */
   xhr.addEventListener('readystatechange',function(e){
       console.log(e);
       let response=e.currentTarget.response?JSON.parse(e.currentTarget.response):null;
       if (e.currentTarget.readyState===4&&response) {
           callback(100,response);
           xhr.upload.removeEventListener('progress', uploadProgress, false)
       }
   },false);

   xhr.open('POST', url, true);  // The third parameter is async? Asynchronous / synchronous
   xhr.setRequestHeader("accessToken",token);
   xhr.send(form);
}

export default {
   uploadForImage:uploadForImage//Native js starts to upload and monitors the upload progress
};

Topics: github Attribute JSON