Effect:
Js image upload function to achieve the effect of the realization, first see the figure to pressure
Principle:
Structure: input tag
You may not have noticed before, but the input tag also does this.
- 1. The type attribute is file
- 2. Accept indicates the file format that is allowed to be selected (if it is a picture, no other file format will appear in the popbox).
- 3. The argument to the onChange callback is the file object data of our choice.
As follows:
<input type='file' accept='image/*' onChange={this.handleSelectFile.bind(this,this.state.uploadUrl)} />
Copy the code
Js part: Ajax request
By instantiating the XMLHttpRequest object, the ajax request is initiated, and the progress and readyState value are monitored to obtain the return value of the back-end to complete the upload.
Note:
- 1. The image upload function can separate the selection process from the upload process. For example, if you select an image, you can preview the image, you can select and preview the image several times, and finally confirm the upload!
- 2. Can modify the code itself, can be applied to upload video or other files!
Github:github.com/Amy-Tong126…
The UI part of the picture uploading function is realized based on ANTD. If antD is not used, it can be replaced in the corresponding position. The specific code is as follows:
JSX:
import React, { Component } from 'react';
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 the file object contents
src:"".// Save the url of the image
progress:0.// Upload progress
uploadUrl:"http://192.168.1.20:13003/fileDetail/upImg/1/3139".// Upload the address}}/* Trigger input click event */ when clicking upload
clickUploadBtn(){
this.refs.uploadInput.click();
}
/* * Select the image to upload * */
handleSelectFile(uploadUrl,e){
const file = e.target.files[0];
if(! file) {return;
}
let src;
// Matches a string of type image/
if (file.type==="image/png"||file.type==="image/jpeg") {
src = URL.createObjectURL(file);
}else{
message.error("Image upload only supports JPG/PNG format, please upload again!");
return;
}
if (file.size/1024/1024>5) {
message.error("The uploaded image size should not exceed 5MB, please re-upload!");
return;
}
this.setState({
file:file,
src:src
});
this.startUpload(uploadUrl,file);
}
/* * Start uploading pictures * */
startUpload(uploadUrl,file){
let this_=this;
/* * Call upload image encapsulation method * */
uploadFunction.uploadForImage(
uploadUrl,
file,
function (progress,response) {// The callback function processes the progress and returns the value of the back end
this_.setState({
progress:progress
});
if (response&&response.code === 200) {
message.success("Upload successful!");
}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;
Copy the code
The uploadFunction function introduced above looks like this:
function uploadForImage(url,data,callback,token) {// Data is 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 argument is useCapture? , whether to use event capture/bubbling
/* * listen for readyState changes and call back the response * */ returned from the back end 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 argument is async? , asynchronous/synchronous
xhr.setRequestHeader("accessToken",token);
xhr.send(form);
}
export default {
uploadForImage:uploadForImage// Native JS starts uploading and listens for upload progress
};
Copy the code