我正在构建一个Laravel 5.4应用程序,让您将图像上传到每个注册的条目。我正在使用干预图像包,但意识到我需要一种方法来启用图像裁剪和旋转(由于某种原因上传时iphone图像被旋转),所以我决定使用jquery插件Slim Cropper。我已将必要的文件添加到我的代码中,但无法成功上传图像。
Slim Cropper提供了两种上传图片的方式:通过提交后提供"TokenMismatchException in VerifyCsrfToken.php (line 68)"
的常规表单,以及只显示“无法上传”消息的ajax表单。我已尝试过两种方式进行不同的更改但无法使其工作。我的所有类/控制器都检查身份验证,并且我已经尝试过以我能想到的方式发送csrf令牌,所有这些都显示相同的错误。
更新:根据评论中的建议,我在<form>
之后立即移动了csrf令牌,我更新了输入文件名以匹配示例中的那些并尝试通过中间件调试而没有错误消息无论如何。 TokenMismatchException
错误不再是问题,但提交表单后,我会收到Constant expression contains invalid operations in Slim.php (line 106)
的错误public static function saveFile($data, $name, $path = public_path('/uploads/mascotas-img/'), $uid = true)
。仍然无法解决这个问题。
以下是代码:
路线
Route::post('/mascotas/avatar', 'PetsController@avatar');
宠物控制器
use App\Slim;
public function avatar(Request $request)
{
if ( $request->avatar )
{
// Pass Slim's getImages the name of your file input, and since we only care about one image, postfix it with the first array key
$image = Slim::getImages('avatar')[0];
$mascota_num = $image['meta']->petId;
// Grab the ouput data (data modified after Slim has done its thing)
if ( isset($image['output']['data']) )
{
// Original file name
$name = $image['output']['name'];
//$name = $request->input('mascota_num');
// Base64 of the image
$data = $image['output']['data'];
// Server path
$path = public_path('/uploads/mascotas-img/');
// Save the file to the server
$file = Slim::saveFile($data, $name, $path);
// Get the absolute web path to the image
$imagePath = public_path('/uploads/mascotas-img/' . $file['name']);
DB::table('mascotas')
->where('num',$mascota_num)
->update(['foto' => $imagePath]);
//$mascota->foto = $imagePath;
//$mascota->save();
}
}
return redirect()->back()->with('success', "User's profile picture has been updated!");
}
超薄班级
namespace App;
abstract class SlimStatus {
const Failure = 'failure';
const Success = 'success';
}
class Slim {
public static function getImages($inputName = 'slim') {
$values = Slim::getPostData($inputName);
// test for errors
if ($values === false) {
return false;
}
// determine if contains multiple input values, if is singular, put in array
$data = array();
if (!is_array($values)) {
$values = array($values);
}
// handle all posted fields
foreach ($values as $value) {
$inputValue = Slim::parseInput($value);
if ($inputValue) {
array_push($data, $inputValue);
}
}
// return the data collected from the fields
return $data;
}
// $value should be in JSON format
private static function parseInput($value) {
// if no json received, exit, don't handle empty input values.
if (empty($value)) {return null;}
// The data is posted as a JSON String so to be used it needs to be deserialized first
$data = json_decode($value);
// shortcut
$input = null;
$actions = null;
$output = null;
$meta = null;
if (isset ($data->input)) {
$inputData = isset($data->input->image) ? Slim::getBase64Data($data->input->image) : null;
$input = array(
'data' => $inputData,
'name' => $data->input->name,
'type' => $data->input->type,
'size' => $data->input->size,
'width' => $data->input->width,
'height' => $data->input->height,
);
}
if (isset($data->output)) {
$outputData = isset($data->output->image) ? Slim::getBase64Data($data->output->image) : null;
$output = array(
'data' => $outputData,
'width' => $data->output->width,
'height' => $data->output->height
);
}
if (isset($data->actions)) {
$actions = array(
'crop' => $data->actions->crop ? array(
'x' => $data->actions->crop->x,
'y' => $data->actions->crop->y,
'width' => $data->actions->crop->width,
'height' => $data->actions->crop->height,
'type' => $data->actions->crop->type
) : null,
'size' => $data->actions->size ? array(
'width' => $data->actions->size->width,
'height' => $data->actions->size->height
) : null
);
}
if (isset($data->meta)) {
$meta = $data->meta;
}
// We've sanitized the base64data and will now return the clean file object
return array(
'input' => $input,
'output' => $output,
'actions' => $actions,
'meta' => $meta
);
}
// $path should have trailing slash
public static function saveFile($data, $name, $path = public_path('/uploads/mascotas-img/'), $uid = true) {
// Add trailing slash if omitted
if (substr($path, -1) !== '/') {
$path .= '/';
}
// Test if directory already exists
if(!is_dir($path)){
mkdir($path, 0755);
}
// Let's put a unique id in front of the filename so we don't accidentally overwrite older files
if ($uid) {
$name = uniqid() . '_' . $name;
}
$path = $path . $name;
// store the file
Slim::save($data, $path);
// return the files new name and location
return array(
'name' => $name,
'path' => $path
);
}
public static function outputJSON($status, $fileName = null, $filePath = null) {
header('Content-Type: application/json');
if ($status !== SlimStatus::Success) {
echo json_encode(array('status' => $status));
return;
}
echo json_encode(
array(
'status' => $status,
'name' => $fileName,
'path' => $filePath
)
);
}
/**
* Gets the posted data from the POST or FILES object. If was using Slim to upload it will be in POST (as posted with hidden field) if not enhanced with Slim it'll be in FILES.
* @param $inputName
* @return array|bool
*/
private static function getPostData($inputName) {
$values = array();
if (isset($_POST[$inputName])) {
$values = $_POST[$inputName];
}
else if (isset($_FILES[$inputName])) {
// Slim was not used to upload this file
return false;
}
return $values;
}
/**
* Saves the data to a given location
* @param $data
* @param $path
*/
private static function save($data, $path) {
file_put_contents($path, $data);
}
/**
* Strips the "data:image..." part of the base64 data string so PHP can save the string as a file
* @param $data
* @return string
*/
private static function getBase64Data($data) {
return base64_decode(preg_replace('#^data:image/\w+;base64,#i', '', $data));
}
}
图片提交表单(tokenmismatch错误)
<form action="{{ url('mascotas/avatar') }}" method="post" enctype="multipart/form-data">
<div class="modal-body">
<div class="slim" data-label="Agregar imagen aquí" data-size="400, 400" data-ratio="1:1" data-meta-pet-id="{{ $mascota->num }}">
@if ( $mascota->foto )
<img src="{{ url('/uploads/mascotas-img/'.$mascota->foto) }}" />
@endif
<input type="file" name="avatar" required />
{{ csrf_field() }}
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="submit" class="btn btn-red">Cambiar Foto</button>
</div>
</form>
备用提交表单(错误消息)
<div class="modal-body">
<div class="slim" data-label="Agregar imagen aquí" data-size="400, 400" data-ratio="1:1" data-service="{{ url('mascotas/avatar') }}" data-meta-pet-id="{{ $mascota->num }}">
@if ( $mascota->foto )
<img src="{{ url('/uploads/mascotas-img/'.$mascota->foto) }}" />
@endif
<input type="file" name="avatar" />
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="submit" class="btn btn-red">Cambiar Foto</button>
</div>
使用示例http://slimimagecropper.com/
的Slim image cropper网站我的原始上传表单通过laravel图像干预,这在上传时没有问题,但非常想用以上其中一个替换。
<form enctype="multipart/form-data" action="{{ url('mascotas/foto') }}" method="POST">
<div class="modal-body">
<img class="mascota-avatar" src="{{ url('/uploads/mascotas-img/'.$mascota->foto) }}">
<div class="clearfix"></div>
<input type="file" name="foto">
<input type="hidden" name="_token" value="{{ csrf_token() }}">
<input type="hidden" name="mascota_num" value="{{ $mascota->num }}">
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="submit" class="btn btn-red">Cambiar Foto</button>
</div>
</form>
感谢您的帮助!
答案 0 :(得分:1)
您应该在每个表单上包含{{ csrf_field() }}
,对于Ajax表单,您可以将标记作为标题发送。