Javascript 如何在Ant Design Upload组件中设置customRequest以使用XMLHttpRequest?
我的部件一团糟。现在我通过一个函数,我已经尝试了一百万件事情,我不能让它工作Javascript 如何在Ant Design Upload组件中设置customRequest以使用XMLHttpRequest?,javascript,reactjs,xmlhttprequest,antd,Javascript,Reactjs,Xmlhttprequest,Antd,我的部件一团糟。现在我通过一个函数,我已经尝试了一百万件事情,我不能让它工作 export default class DatafileUpload extends Component { initialState = { fileUploading: false, fileList: [], status: 'empty', // 'empty' | 'active' | 'success' | 'exception' file: {} } sta
export default class DatafileUpload extends Component {
initialState = {
fileUploading: false,
fileList: [],
status: 'empty', // 'empty' | 'active' | 'success' | 'exception'
file: {}
}
state = this.initialState
static propTypes = {
userId: PropTypes.string.isRequired,
datasetId: PropTypes.string.isRequired
}
scrubFilename = (filename) => filename.replace(/[^\w\d_\-.]+/ig, '')
requestSignedS3Url = (file) => {
const filename = this.scrubFilename(file.name)
const params = {
userId: this.props.userId,
contentType: file.type,
Key: `${filename}`
};
return api.get('/s3/signUpload', { params })
.then(response => {
return response.data;
})
.catch(error => {
console.error(error);
});
}
uploadFile = (file) => {
this.requestSignedS3Url(file)
.then(signResult => this.uploadToS3(file, signResult))
.catch(error => console.log(error))
}
createCORSRequest = (method, url, opts) => {
opts = opts || {};
let xhr = new XMLHttpRequest();
if (xhr.withCredentials != null) {
xhr.open(method, url, true);
if (opts.withCredentials != null) {
xhr.withCredentials = opts.withCredentials;
}
} else if (typeof XDomainRequest !== "undefined") {
xhr = new XDomainRequest();
xhr.open(method, url);
} else {
xhr = null;
}
return xhr;
};
stepFunctions = () => {
return {
preprocess: (file) => {
console.log('Pre-process: ' + file.name);
},
onProgress: (percent, message, file) => {
this.setState({ fileUploading: true })
console.log('Upload progress: ' + percent + '% ' + message);
},
onFinish: (signResult) => {
this.setState({ fileUploading: false })
console.log("Upload finished: " + signResult.publicUrl)
},
onError: (message) => {
this.setState({ fileUploading: false })
console.log("Upload error: " + message);
},
scrubFilename: (filename) => {
return filename.replace(/[^\w\d_\-\.]+/ig, '');
},
onFinishS3Put: (signResult, file) => {
console.log(signResult)
return console.log('base.onFinishS3Put()', signResult.publicUrl);
}
}
}
uploadToS3 = async (file, signResult) => {
const xhr = await this.createCORSRequest('PUT', signResult.signedUrl);
const functions = this.stepFunctions()
functions.preprocess(file)
if (!xhr) {
functions.onError('CORS not supported', file);
} else {
xhr.onload = () => {
if (xhr.status === 200) {
functions.onProgress(100, 'Upload completed', file);
return functions.onFinishS3Put('potatopotato', file);
} else {
return functions.onError('Upload error: ' + xhr.status, file);
}
};
xhr.onerror = () => {
return functions.onError('XHR error', file);
};
xhr.upload.onprogress = (e) => {
let percentLoaded;
if (e.lengthComputable) {
percentLoaded = Math.round((e.loaded / e.total) * 100);
return functions.onProgress(percentLoaded, percentLoaded === 100 ? 'Finalizing' : 'Uploading', file);
}
};
}
xhr.setRequestHeader('Content-Type', file.type);
if (signResult.headers) {
const signResultHeaders = signResult.headers
Object.keys(signResultHeaders).forEach(key => {
const val = signResultHeaders[key];
xhr.setRequestHeader(key, val);
})
}
xhr.setRequestHeader('x-amz-acl', 'public-read');
this.httprequest = xhr;
return xhr.send(file);
};
handleChange = ({ file, fileList }) => {
const functions = this.stepFunctions()
functions.preprocess(file)
if (!file) {
functions.onError('CORS not supported', file);
} else {
file.onload = () => {
if (file.status === 200) {
functions.onProgress(100, 'Upload completed', file);
return functions.onFinishS3Put('potatopotato', file);
} else {
return functions.onError('Upload error: ' + file.status, file);
}
};
file.onerror = () => {
return functions.onError('XHR error', file);
};
file.upload.onprogress = (e) => {
let percentLoaded;
if (e.lengthComputable) {
percentLoaded = Math.round((e.loaded / e.total) * 100);
return functions.onProgress(percentLoaded, percentLoaded === 100 ? 'Finalizing' : 'Uploading', file);
}
};
}
console.log('File: ', file)
// always setState
this.setState({ fileList });
}
render() {
const props = {
onChange: this.handleChange,
multiple: true,
name: "uploadFile",
defaultFileList: this.initialState.fileList,
data: this.uploadFile,
listType: "text",
customRequest: ????,
showUploadList: {
showPreviewIcon: true,
showRemoveIcon: true
},
onProgress: ( {percent} ) => {
this.setState({ fileUploading: true })
console.log('Upload progress: ' + percent + '% ' );
},
onError: (error, body) => {
this.setState({ fileUploading: false })
console.log("Upload error: " + error);
},
onSuccess: (body)=> {
console.log(body)
return console.log('base.onFinishS3Put()');
}
};
return (
<Upload {...props} fileList={this.state.fileList}>
<Button>
<Icon type="upload" /> Upload
</Button>
</Upload>
)
}
}
导出默认类DatafileUpload扩展组件{
初始状态={
文件上载:false,
文件列表:[],
状态:'empty',//'empty'|'active'|'success'|'exception'
文件:{}
}
state=this.initialState
静态类型={
userId:PropTypes.string.isRequired,
datasetId:PropTypes.string.isRequired
}
scrubFilename=(filename)=>filename.replace(/[^\w\d \-.]+/ig,”)
requestSignedS3Url=(文件)=>{
const filename=this.scrubFilename(file.name)
常量参数={
userId:this.props.userId,
contentType:file.type,
键:`${filename}`
};
返回api.get('/s3/signUpload',{params})
。然后(响应=>{
返回响应数据;
})
.catch(错误=>{
控制台错误(error);
});
}
上传文件=(文件)=>{
此.requestSignedS3Url(文件)
.then(signResult=>this.uploadToS3(文件,signResult))
.catch(错误=>console.log(错误))
}
createCORSRequest=(方法、url、选项)=>{
opts=opts |{};
设xhr=newXMLHttpRequest();
if(xhr.withCredentials!=null){
open(方法、url、true);
if(opts.withCredentials!=null){
xhr.withCredentials=opts.withCredentials;
}
}else if(XDomainRequest的类型!=“未定义”){
xhr=新的XDomainRequest();
open(方法,url);
}否则{
xhr=null;
}
返回xhr;
};
步骤函数=()=>{
返回{
预处理:(文件)=>{
console.log('预处理:'+文件名);
},
onProgress:(百分比、消息、文件)=>{
this.setState({fileUploading:true})
log('上载进度:'+百分比+'%'+消息);
},
onFinish:(signResult)=>{
this.setState({fileUploading:false})
log(“上传完成:”+signResult.publicUrl)
},
OneError:(消息)=>{
this.setState({fileUploading:false})
console.log(“上传错误:+消息”);
},
scrubFilename:(文件名)=>{
返回文件名。替换(/[^\w\d\u\-\.]+/ig',);
},
onfins3put:(signResult,file)=>{
console.log(signResult)
返回console.log('base.onfinish3put()',signResult.publicUrl);
}
}
}
uploadToS3=异步(文件,签名结果)=>{
const xhr=wait this.createCORSRequest('PUT',signResult.signedUrl);
const functions=this.stepFunctions()
函数。预处理(文件)
如果(!xhr){
functions.onError(“不支持验尸官”,文件);
}否则{
xhr.onload=()=>{
如果(xhr.status==200){
onProgress(100,“上传完成”,文件);
返回函数.onfinish3put('potatopato',file);
}否则{
return functions.onError('上传错误:'+xhr.status,文件);
}
};
xhr.onerror=()=>{
返回函数.onError('XHR error',file);
};
xhr.upload.onprogress=(e)=>{
让百分比加载;
if(如长度可计算){
加载百分比=数学整轮((加载/总计)*100);
返回函数.onProgress(加载百分比,加载百分比===100?“正在完成”:“正在上载”,文件);
}
};
}
setRequestHeader('Content-Type',file.Type);
if(signResult.headers){
const signResultHeaders=signResult.headers
Object.key(signResultHeaders.forEach)(key=>{
const val=signResultHeaders[key];
setRequestHeader(key,val);
})
}
setRequestHeader('x-amz-acl','public read');
this.httprequest=xhr;
返回xhr.send(文件);
};
handleChange=({file,fileList})=>{
const functions=this.stepFunctions()
函数。预处理(文件)
如果(!文件){
functions.onError(“不支持验尸官”,文件);
}否则{
file.onload=()=>{
如果(file.status==200){
onProgress(100,“上传完成”,文件);
返回函数.onfinish3put('potatopato',file);
}否则{
return functions.onError('上传错误:'+file.status,file);
}
};
file.onerror=()=>{
返回函数.onError('XHR error',file);
};
file.upload.onprogress=(e)=>{
让百分比加载;
if(如长度可计算){
加载百分比=数学整轮((加载/总计)*100);
返回函数.onProgress(加载百分比,加载百分比===100?“正在完成”:“正在上载”,文件);
}
};
}
console.log('文件:',文件)
//始终设置状态
this.setState({fileList});
}
render(){
常量道具={
onChange:this.handleChange,
多重:对,
名称:“上传文件”,
defaultFileList:this.initialState.fileList,
数据:this.uploadFile,
列表类型:“文本”,
客户请求:????,
显示上载列表:{
是的,
showremovicon:对
},
onProgress:({percent})=>{
this.setState({fileUploading:true})
log('Upload progress:'+percent+'%');
},
onError:(错误,正文)=>{
this.setState({fileUploading:false})
日志(“上传错误:+错误”);
},
onSuccess:(body)=>{
控制台日志(正文)
返回console.log('base.onfinish3put()');
}
};
返回(
上传
)
}
}
我知道这段代码乱七八糟,毫无意义,到处都是重复的数据。我想让它工作,然后清理/optimse。基本上,我无法使用onChange更新组件进度条,也无法尝试使用
<Upload name="file" customRequest={this.customRequest} onChange={this.onChange}>
<Button>
<Icon type="upload" /> Click to Upload
</Button>
</Upload>
...
onChange = (info) => {
const reader = new FileReader();
reader.onloadend = (obj) => {
this.imageDataAsURL = obj.srcElement.result;
};
reader.readAsDataURL(info.file.originFileObj);
...
};
...
customRequest = ({ onSuccess, onError, file }) => {
const checkInfo = () => {
setTimeout(() => {
if (!this.imageDataAsURL) {
checkInfo();
} else {
this.uploadFile(file)
.then(() => {
onSuccess(null, file);
})
.catch(() => {
// call onError();
});
}
}, 100);
};
checkInfo();
};
handleUplaod = (file: any) => {
return new Promise(async (resolve, reject) => {
const fileName = `nameThatIwant.type`;
const url = await S3Fetcher.getPresignedUrl(fileName);
resolve(url);
});
render(){
return(
....
<Upload
action={this.handleUplaod}
....
Upload>
....
fileReader = new FileReader();
.....
onChange = (info) => {
if (!this.fileReader.onloadend) {
this.fileReader.onloadend = (obj) => {
this.setState({
image: obj.srcElement.result, //will be used for knowing load is finished.
});
};
// can be any other read function ( any reading function from
// previously created instance can be used )
this.fileReader.readAsArrayBuffer(info.file.originFileObj);
}
};
customRequest = async option => {
const { onSuccess, onError, file, action, onProgress } = option;
const url = action;
await new Promise(resolve => this.waitUntilImageLoaded(resolve)); //in the next section
const { image } = this.state; // from onChange function above
const type = 'image/png';
axios
.put(url, Image, {
onUploadProgress: e => {
onProgress({ percent: (e.loaded / e.total) * 100 });
},
headers: {
'Content-Type': type,
},
})
.then(respones => {
/*......*/
onSuccess(respones.body);
})
.catch(err => {
/*......*/
onError(err);
});
};
waitUntilImageLoaded = resolve => {
setTimeout(() => {
this.state.image
? resolve() // from onChange method
: this.waitUntilImageLoaded(resolve);
}, 10);
};
render(){
return(
....
<Upload
onChange={this.onChange}
customRequest={this.customRequest}
...>
onCustomRequest = file => {
return new Promise(((resolve, reject) => {
const ajaxResponseWasFine = true;
setTimeout(() => {
if (ajaxResponseWasFine) {
const reader = new FileReader();
reader.addEventListener('load', () => {
resolve(reader.result);
}, false);
if (file) {
reader.readAsDataURL(file);
}
} else {
reject('error');
}
}, 1000);
}));
};
<Dragger
action={this.onCustomRequest}
fileList={fileList}
onChange={this.handleChangeUpload}
className={styles.dragWrapper}
showUploadList={true}
beforeUpload={this.beforeUpload}
>