vue-image-crop-upload icon indicating copy to clipboard operation
vue-image-crop-upload copied to clipboard

crop success, but upload fail (with laravel)

Open zhengfen opened this issue 7 years ago • 5 comments
trafficstars

solved

edit file upload-2.vue: (at line 828) replace

new Promise(function(resolve, reject) {
				let client = new XMLHttpRequest();
				client.open('POST', url, true);
				client.withCredentials = withCredentials;
				client.onreadystatechange = function() {
					if (this.readyState !== 4) {
						return;
					}
					if (this.status === 200 || this.status === 201) {
						resolve(JSON.parse(this.responseText));
					} else {
						reject(this.status);
					}
				};
				client.upload.addEventListener("progress", uploadProgress, false); //监听进度
				// 设置header
				if (typeof headers == 'object' && headers) {
					Object.keys(headers).forEach((k) => {
						client.setRequestHeader(k, headers[k]);
					})
				}
				client.send(fmData);
			})

to

axios.post(url, fmData)

zhengfen avatar Mar 20 '18 20:03 zhengfen

solved by: send cropped image blob with axios axios.post(url, fmData)

zhengfen avatar Jun 04 '18 21:06 zhengfen

@zhengfen How did you manage to do that? It seems like we cannot customize the uploading process so the only way to handle the upload ourselves is to do it on the event crop-success. I tried the following:

handleSuccessfulCrop(imgUrl) { 
  const formData = new FormData();
  formData.append("file", imgUrl);

  axios.post("/api/users/profile_photo", formData)
  /// etc.....

}

But it doesn't work. It fails the laravel validations that I have:

  • file input must be a file
  • file input must be an image.

I tried googling for a function to convert a base64 string to an image (blob) but when I try to parse it I get an error saying

"InvalidCharacterError: Failed to execute 'atob' on 'Window': The string to be decoded is not correctly encoded."

FrenchMajesty avatar Jul 03 '18 21:07 FrenchMajesty

edit file upload-2.vue: (at line 828) replace

new Promise(function(resolve, reject) {
				let client = new XMLHttpRequest();
				client.open('POST', url, true);
				client.withCredentials = withCredentials;
				client.onreadystatechange = function() {
					if (this.readyState !== 4) {
						return;
					}
					if (this.status === 200 || this.status === 201) {
						resolve(JSON.parse(this.responseText));
					} else {
						reject(this.status);
					}
				};
				client.upload.addEventListener("progress", uploadProgress, false); //监听进度
				// 设置header
				if (typeof headers == 'object' && headers) {
					Object.keys(headers).forEach((k) => {
						client.setRequestHeader(k, headers[k]);
					})
				}
				client.send(fmData);
			})

to

axios.post(url, fmData)

zhengfen avatar Jul 14 '18 19:07 zhengfen

解决了,谢谢大佬!

liuzhenjie0311 avatar Oct 24 '19 08:10 liuzhenjie0311

Finally I did it after hours of overthinking it, here's my solution:

First replace the promise in the upload function by this:

axios.post(url, fmData) .then((response)=>{ that.loading = 2; that.$emit('crop-upload-success', response, field, ki); }) .catch((err) => { that.loading = 3; that.hasError = true; that.errorMsg = lang.fail; that.$emit('crop-upload-fail', err, field, ki); })

now you can receive the image as a normal file upload in your controller:

$image = $request->file('avatar'); $path = $request->avatar->store('avatars'); // save your file name $path in bd

Note: make sure you have configured laravel file system correctly

sid3r avatar Nov 06 '19 20:11 sid3r