laravel-5 - 在 laravel 的控制器中保存 blob 图像
问题描述
在我的 Laravel 5/vuejs 2.6 中,我使用 vue-upload-component 上传图像并发送请求的图像 blob,我尝试使用控制器代码将其保存,例如:
if ( !empty($requestData['avatar_filename']) and !empty($requestData['avatar_blob']) ) {
$dest_image = 'public/' . Customer::getUserAvatarPath($newCustomer->id, $requestData['avatar_filename']);
$requestData['avatar_blob']= str_replace('blob:','',$requestData['avatar_blob']);
Storage::disk('local')->put($dest_image, file_get_contents($requestData['avatar_blob']));
ImageOptimizer::optimize( storage_path().'/app/'.$dest_image, null );
} // if ( !empty($page_content_image) ) {
结果,我上传了一张图片,但它不可读。源文件有 5 Kib,生成的文件有 5.8 Kib,在浏览器的控制台中,我看到 blob 路径为
avatar_blob: "blob:http://local-hostels2.com/91a18493-36a7-4023-8ced-f5ea4a3c58af"
我必须转换我的 blob 以正确保存它吗?
修改:更详细一点:在 vue 文件中,我使用 axios 发送请求:
let customerRegisterArray =
{
username: this.previewCustomerRegister.username,
email: this.previewCustomerRegister.email,
first_name: this.previewCustomerRegister.first_name,
last_name: this.previewCustomerRegister.last_name,
account_type: this.previewCustomerRegister.account_type,
phone: this.previewCustomerRegister.phone,
website: this.previewCustomerRegister.website,
notes: this.previewCustomerRegister.notes,
avatar_filename: this.previewCustomerRegister.avatarFile.name,
avatar_blob: this.previewCustomerRegister.avatarFile.blob,
};
console.log("customerRegisterArray::")
console.log(customerRegisterArray)
axios({
method: ('post'),
url: window.API_VERSION_LINK + '/customer_register_store',
data: customerRegisterArray,
}).then((response) => {
this.showPopupMessage("Customer Register", 'Customer added successfully ! Check entered email for activation link !', 'success');
alert( "SAVED!!::"+var_dump() )
}).catch((error) => {
});
并且 this.previewCustomerRegister.avatarFile.blob 具有值:“blob: http: //local-hostels2.com/91a18493-36a7-4023-8ced-f5ea4a3c58af ”其中http://local-hostels2.com是我的主机...我将此值设置为预览图像定义为:
<img
class="img-preview-wrapper"
:src="previewCustomerRegister.avatarFile.blob"
alt="Your avatar"
v-show="previewCustomerRegister.avatarFile.blob"
width="256"
height="auto"
id="preview_avatar_file"
>
当 previewCustomerRegister.avatarFile.blob 被分配了上传的文件时,我在预览图像中看到了它。我在第一个主题中显示了带有保存功能的控件,但是当我尝试用 kate 打开生成的文件时,我发现它包含我的容器文件资源/视图/index.blade.php 的内容...
我做错了什么,哪个是有效的方法?
修改块 #2: 我在请求中添加了“内容类型”
axios({
method: ('post'),
url: window.API_VERSION_LINK + '/customer_register_store',
data: customerRegisterArray,
headers: {
'Content-Type': 'multipart/form-data'
}
但是有了它,我的控件中出现了验证错误,因为我用请求定义了控制动作:
public function store(CustomerRegisterRequest $request)
{
并在 app/Http/Requests/CustomerRegisterRequest.php :
<?php
namespace App\Http\Requests;
use App\Http\Traits\funcsTrait;
use Illuminate\Foundation\Http\FormRequest;
use App\Customer;
class CustomerRegisterRequest extends FormRequest
{
use funcsTrait;
public function authorize()
{
return true;
}
public function rules()
{
$request= Request();
$requestData= $request->all();
$this->debToFile(print_r( $requestData,true),' getCustomerValidationRulesArray $requestData::');
/* My debugging method to write data to text file
and with Content-Type defined above I see that $requestData is always empty
and I got validations errors
*/
// Validations rules
$customerValidationRulesArray= Customer::getCustomerValidationRulesArray( $request->get('id'), ['status'] );
return $customerValidationRulesArray;
}
}
在 routes/api.php 中定义:
Route::post('customer_register_store', 'CustomerRegisterController@store');
在我的浏览器控制台中, 我看到:https : //imgur.com/a/0vsPIsa,https://imgur.com/a/wJEbBnP
我想 axios 标头有问题吗?没有'Content-Type'定义我的验证规则工作正常......
修改块#3
我设法使用方法获取 blob,例如:
var self = this;
fetch(this.previewCustomerRegister.avatarFile.blob) .then(function(response) {
console.log("fetch response::")
console.log( response )
if (response.ok) {
return response.blob().then(function(myBlob) {
var objectURL = URL.createObjectURL(myBlob);
// myImage.src = objectURL;
console.log("objectURL::")
console.log( objectURL )
console.log("self::")
console.log( self )
let customerRegisterArray =
{
username: self.previewCustomerRegister.username,
email: self.previewCustomerRegister.email,
first_name: self.previewCustomerRegister.first_name,
last_name: self.previewCustomerRegister.last_name,
account_type: self.previewCustomerRegister.account_type,
phone: self.previewCustomerRegister.phone,
website: self.previewCustomerRegister.website,
notes: self.previewCustomerRegister.notes,
avatar_filename: self.previewCustomerRegister.avatarFile.name,
avatar: objectURL,
};
console.log("customerRegisterArray::")
console.log(customerRegisterArray)
axios({
method: 'POST',
url: window.API_VERSION_LINK + '/customer_register_store',
data: customerRegisterArray,
// headers: {
// 'Content-Type': 'multipart/form-data' // multipart/form-data - as we need to upload with image
// }
}).then((response) => {
self.is_page_updating = false
self.message = ''
self.showPopupMessage("Customer Register", 'Customer added successfully ! Check entered email for activation link !', 'success');
alert( "SAVED!!::")
}).catch((error) => {
self.$setLaravelValidationErrorsFromResponse(error.response.data);
self.is_page_updating = false
self.showRunTimeError(error, this);
self.showPopupMessage("Customer Register", 'Error adding customer ! Check Details fields !', 'warn');
// window.grecaptcha.reset()
self.is_recaptcha_verified = false;
self.$refs.customer_register_wizard.changeTab(3,0)
});
});
} else {
return response.json().then(function(jsonError) {
// ...
});
}
}).catch(function(error) {
console.log('There has been a problem with your fetch operation: ', error.message);
});
在 objectURL 和 self 我看到正确的值:https ://imgur.com/a/4YvhbFz
1) 但是在 laravel 的控制下检查服务器上的数据时,我看到了与开始尝试上传图像时相同的值:
[avatar_filename] => patlongred.jpg [avatar] => blob: http://local-hostels2.com/d9bf4b66-42b9-4990-9325-a72dc8c3a392
必须以其他方式操作获取的 bnlob 吗?
2)如果我设置:
headers: {
'Content-Type': 'multipart/form-data'
}
我收到验证错误,表明我的数据未正确请求...
?
解决方案
您正在使用请求类型,application/json
因此您将无法以这种方式保存图像,对于文件上传,请求类型应该multipart/form-data
在这种情况下您需要发送请求为
let customerRegisterArray = new FormData();
customerRegisterArray.put('username', this.previewCustomerRegister.username);
customerRegisterArray.put('email', this.previewCustomerRegister.email);
....
customerRegisterArray.put('avatar', this.previewCustomerRegister.avatarFile);
console.log("customerRegisterArray::")
console.log(customerRegisterArray)
axios({
method: ('post'),
url: window.API_VERSION_LINK + '/customer_register_store',
data: customerRegisterArray,
headers: {
'Content-Type': 'multipart/form-data'
}
}).then((response) => {
this.showPopupMessage("Customer Register", 'Customer added successfully !Check entered email for activation link !', 'success');
alert( "SAVED!!::"+var_dump() )
}).catch((error) => {});
推荐阅读
- python - 如何存储科学大(显微镜)文件?
- python - HAAR 人脸检测无法按预期工作
- java - 无法在带有硒的图像轮播中一一点击
- maven - 如何将 Maven 工件从一个存储库复制到另一个存储库
- php - 如何将许多语句 mysql dinamis 转换为 laravel eloquent?
- amazon-web-services - MS-SQL 数据库未添加到 AD 服务?
- kubernetes - 如何为 livenessProbe/readinessProbe 定义 Pod 健康检查端口
- node.js - 世博项目中发生网络请求失败
- floating-point - 浮点值的数值稳定运行平均值
- postgresql - 在 pgadmin4 中使列可编辑