【问题标题】:How to update image with AJAX in Laravel如何在 Laravel 中使用 AJAX 更新图像
【发布时间】:2019-10-25 01:11:28
【问题描述】:

我在使用图像更新记录时遇到问题。我不需要做什么。我的图像存储在一个名为“img/products”的公共文件夹中

ProductController.php

这是我的控制器。不用修改图片也能正常工作。

public function update(Request $request, $id)
    {
        $validator = Validator::make($request->input(), array(
            'name' => 'required',
            'category_id' => 'required',
            'description' => 'required',
            'price_neto' => 'required',
            'iva' => 'required',
            'price_total' => 'required',
            'image' => '',
        ));

        if ($validator->fails()) {
            return response()->json([
                'error'    => true,
                'messages' => $validator->errors(),
            ], 422);
        }

        $products = Product::find($id);

        $products->name = $request->input('name');
        $products->category_id = $request->input('category_id');
        $products->description = $request->input('description');
        $products->price_neto = $request->input('price_neto');
        $products->iva = $request->input('iva');
        $products->price_total = $request->input('price_total');
        $products->image = $request->input('image');

        $products->save();

        return response()->json([
            'error' => false,
            'products'  => $products,
        ], 200);
    }

Product.js

我只知道我必须在 store 函数中使用var formData = new FormData ($ ("# frmAddProduct") [0]);。我可以输入带有图像的记录,但不能编辑它们。我的图像存储在名为“img/products”的公共文件夹中

$(document).ready(function() {

    $("#btn-edit").click(function() {
        $.ajaxSetup({
            headers: {
                'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
            }
        });
        $.ajax({
            type: 'PUT',
            url: '/product/' + $("#frmEditProduct input[name=product_id]").val(),
            data: {
                name: $("#frmEditProduct input[name=name]").val(),
                category_id: $("#frmEditProduct select[name=category_id]").val(),
                description: $("#frmEditProduct input[name=description]").val(),
                price_neto: $("#frmEditProduct input[name=price_neto2]").val(),
                iva: $("#frmEditProduct input[name=iva2]").val(),
                price_total: $("#frmEditProduct input[name=price_total2]").val(),
                image: $("#frmEditProduct input[name=image]").val(),
            },
            dataType: 'json',
            success: function(data) {
                $('#frmEditProduct').trigger("reset");
                $("#frmEditProduct .close").click();
                window.location.reload();
            },
            error: function(data) {
                var errors = $.parseJSON(data.responseText);
                $('#edit-product-errors').html('');
                $.each(errors.messages, function(key, value) {
                    $('#edit-product-errors').append('<li>' + value + '</li>');
                });
                $("#edit-error-bag").show();
            }
        });
    });

});

function editProductForm(product_id) {
    $.ajax({
        type: 'GET',
        url: '/product/' + product_id,
        success: function(data) {
            $("#edit-error-bag").hide();
            $("#frmEditProduct input[name=name]").val(data.products.name);
            $("#frmEditProduct select[name=category_id]").val(data.products.category_id);
            $("#frmEditProduct input[name=description]").val(data.products.description);
            $("#frmEditProduct input[name=price_neto2]").val(data.products.price_neto);
            $("#frmEditProduct input[name=iva2]").val(data.products.iva);
            $("#frmEditProduct input[name=price_total2]").val(data.products.price_total);
            $("#frmEditProduct file[name=image]").val(data.products.image);
            $("#frmEditProduct input[name=product_id]").val(data.products.id);
            $('#editProductModal').modal('show');
        },
        error: function(data) {
            console.log(data);
        }
    });
}

【问题讨论】:

  • 您是否创建了指向存储路径的链接? php工匠存储:链接
  • 不,我没有。我没有使用过该命令,并且我已经可以使用存储和删除功能。 @AlexandreBarbosa
  • 好的,虽然我以更新方法为例进行了回复,但我不确定我是否理解您的情况。因为我想知道您将图像存储在哪里以获取它们。如果要存储在“storage”文件夹中,则必须创建指向存储的链接。但是,如果您将图像作为其他“资产”存储在公用文件夹中,则解决方案会有所不同。
  • 图片存储在公共文件夹('image/products/')@AlexandreBarbosa
  • 请看我答案的结尾,看看它是否可以根据您的需要帮助您。我编辑了我的答案。

标签: javascript php html ajax laravel


【解决方案1】:

你应该在尝试删除之前检查文件是否存在,例如:

 $product = Product::find($id);

 if(!$product)
 {
     return response()->json(['error' => 'Product not found'], 404);
 }

 if (Storage::disk('local')->exists('img/products/'.$product->image)) {
    Storage::disk('local')->delete('img/products/'.$product->image);
 }

只看一个例子:

public function update(UpdateProductFormRequest $request, $id)
{
     $product = Product::find($id); 

     $data = $request->only('name','category_id','description',
                               'price_neto','iva','price_total');

     if(!$product)
     {
         return response()->json(['error' => 'Product not found'], 404);
     }

     // when saving the file, delete the old file first
     if ($request->hasFile('image')) {

        $file              = $request->file('image');

        $original_filename = $file->getClientOriginalName();
        // $mime           = $file->getMimeType();  // Suggestion
        $extention         = $file->getExtension();
        // $size           = $file->getClientSize(); // Suggestion

        $stored_filename   = $original_filename; // md5($original_filename); // Suggestion 
        $file_path         = storage_path('public/img/products/');


        if (Storage::disk('local')
                  ->exists("public/img/products/{$stored_filename}.{$extention}")) 
        {
            Storage::disk('local')
                  ->delete("public/img/products/{$recordSet->stored_filename}.{$extention}");
        } 
        $file_moved = $file->move($file_path, "{$stored_filename}.{$extention}");
        $data->image = "{$stored_filename}.{$extention}";
     }

     // Updating data    
     $result = $product->update($data);

     if ($result) {
        /* return redirect()
                ->route('products.index')
                ->withSuccess('Product was successfully updated'); */

         return response()->json([
              'message' => 'Product was successfully updated'
              'product' => $product
         ]); // You don't have to put 200 because it's the default
     }


     /* return back()
        ->withErrors(['Unable to update the product'])
        ->withInput($request->input()); */

     return response()->json(['error' => 'Unable to update the product'], 400);
}

如果您创建一个表单请求来进行验证会更好。

不要忘记创建指向存储路径的链接:

 php artisan storage:link 

我认为这会有所帮助:

 $("#btn-edit").click(function() {

    var formData = new FormData($("#frmAddProduct")[0]);
    formData.append('_method', 'put');
    formData.append('_token', "{{ csrf_token() }}"); // if you are using Blade

    var route= "{{ route('products.update', ['id' => ':id']) }}"; // if you are using Blade
    route= route.replace(':id', $("#frmEditProduct input[name=product_id]").val())

    $.ajax({
        method: 'post',
        url: route,
        data: formData,
        dataType: 'json',
        success: function(data) {
            $('#frmEditProduct').trigger("reset");
            $("#frmEditProduct .close").click();
            window.location.reload();
        },
        error: function(data) {
            var errors = $.parseJSON(data.responseText);
            $('#edit-product-errors').html('');
            $.each(errors.messages, function(key, value) {
                $('#edit-product-errors').append('<li>' + value + '</li>');
            });
            $("#edit-error-bag").show();
        }
    });
});

你的js脚本在“刀锋”中吗?如果是这样,请尝试以下方式:

var image = '{{ asset("/img/products/_image_file") }}'

image.replace('_image_file', data.products.image)

$("#frmEditProduct file[name=image]").val(image)

请注意,我们可以首先使用“asset()”帮助器来创建用于查找图像的完整路径,但使用“_image_file”占位符 之后,我们使用replace()函数将“_image_file”占位符更改为ajax响应带来的实际图像文件。

【讨论】:

  • 对不起,我会编辑帖子!从“存储”方法更改为“更新”方法!
  • 图片存放在公用文件夹怎么办?
  • 你可以使用asset()方法
  • 是的,正如@jigs_ 回复的那样,您可以在 Blade 中使用asset() 助手,如下所示: image }") }}" />
  • 你的剧本在“刀锋”中吗?如果是这样,请这样尝试: var image = '{{asset("/img/products/_image_file") }}' image.replace('_image_file', data.products.image) $("#frmEditProduct file[name =image]").val(data.products.image)
【解决方案2】:

这样的?

ProductController.php

public function update(Request $request, $id)
    {

        $validator = Validator::make($request->input(), array(
            'name' => 'required',
            'category_id' => 'required',
            'description' => 'required',
            'price_neto' => 'required',
            'iva' => 'required',
            'price_total' => 'required',
            'image' => '',
        ));

        if ($validator->fails()) {
            return response()->json([
                'error'    => true,
                'messages' => $validator->errors(),
            ], 422);
        }

        $products = Product::find($id);

        if ($request->hasFile('image')) {

            $productImage = $request->file('image');           
            $productImageName = rand() . '.' . $productImage->getClientOriginalExtension();

            if (Storage::disk('local')->exists("img/products/{$productImageName}")) {
                Storage::disk('local')->delete("img/products/{$recordSet->$productImageName}");
            }

            $file_moved  = $productImage->move(public_path('img/products'), $productImageName);
            $data->image = "{$productImageName}";
        }

        $products->save([
            'name'          => $request->name,
            'category_id'   => $request->category_id,
            'description'   => $request->description,
            'price_neto'    => $request->price_neto,
            'iva'           => $request->iva,
            'price_total'   => $request->price_total,
            'image'         => $productImageName,
        ]);

        return response()->json([
            'error' => false,
            'products'  => $products,
        ]);

    }

Product.js

$("#btn-edit").click(function() {

        var formData = new FormData($("#frmEditProduct")[0]);
        formData.append('_method', 'put');

        $.ajaxSetup({
            headers: {
                'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
            }
        });
        $.ajax({
            type: 'POST',
            url: '/product/' + $("#frmEditProduct input[name=product_id]").val(),
            data: formData,
            dataType: 'json',
            success: function(data) {
                $('#frmEditProduct').trigger("reset");
                $("#frmEditProduct .close").click();
                window.location.reload();
            },
            error: function(data) {
                var errors = $.parseJSON(data.responseText);
                $('#edit-product-errors').html('');
                $.each(errors.messages, function(key, value) {
                    $('#edit-product-errors').append('<li>' + value + '</li>');
                });
                $("#edit-error-bag").show();
            }
        });
    });

【讨论】:

    猜你喜欢
    • 2023-01-27
    • 2020-02-20
    • 2021-08-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-01
    • 2019-03-03
    相关资源
    最近更新 更多