♩ 背景

  • 昨天在自己的 Laravel5.5 框架项目中,希望集成 Layer 的图片上传功能
  • 但是在 ajax(POST)提交请求时,一直显示 500 报错

♪ 分析

⒈ 问题所在

  • 最后将核心代码摘出,放到 Larvel 框架以外运行,发现代码是没有问题的,因为对 Laravel 框架接触的太浅,忽视了 CSRF 的限制

  • 推荐参考文章:使用中间件 VerifyCsrfToken 避免 CSRF 攻击

⒉ 解决方案

  • 一般在表单提交时,都会存放一个隐藏的输入框
<input type="hidden" name="_token" value="<?PHP echo csrf_token(); ?>">
  • 或者在需要提交的表单中补充一行代码:
<form method="POST" action="/profile">
    {{ csrf_field() }}
    ...
</form>
  • 但是,在比较单一的元素进行 ajax 提交时,建议可使用如下的方法
    ①. 页面中添加隐藏域
<input type="hidden" name="_token" class="tag_token" value="<?PHP echo csrf_token(); ?>">

②. ajax 请求前,先获取 csrf_token()

var tag_token = $(".tag_token").val();

③. ajax 请求时,将该值作为数据的一部分传输过去,例如:

data:{'_token':tag_token}

♫ 实现步骤

⒈ 源文件目录

⒉ 前端准备

  • 页面引入layui 的 css 和 js 文件
<script type="text/javascript" src="layui/layui.js"></script>
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<link rel="stylesheet" type="text/css" href="layui/css/layui.css" />

: 本人下载的 layui 框架源码包为 layui-v2.2.45

  • 核心代码:
<div class="layui-form-item">
        <div class="layui-upload">
            <button type="button" name="img_upload" class="layui-btn btn_upload_img">
                <i class="layui-icon">&#xe67c;</i>上传图片
            </button>
            <img class="layui-upload-img img-upload-view" src="upload/dog.jpg">
            <p id="demoText"></p>
        </div>
    </div>
  • js 代码:
<script type="text/javascript"> layui.use('upload',function(){ var upload = layui.upload; var tag_token = $(".tag_token").val(); //普通图片上传 var uploadInst = upload.render({ elem: '.btn_upload_img',type : 'images',exts: 'jpg|png|gif' //设置一些后缀,用于演示前端验证和后端的验证 //,auto:false //选择图片后是否直接上传 //,accept:'images' //上传文件类型,url: 'upload.PHP',data:{'_token':tag_token},before: function(obj){ //预读本地文件示例,不支持ie8 obj.preview(function(index,file,result){ $('.img-upload-view').attr('src',result); //图片链接(base64) }); },done: function(res){ //如果上传失败 if(res.status == 1){ return layer.msg('上传成功'); }else{//上传成功 layer.msg(res.message); } },error: function(){ //演示失败状态,并实现重传 return layer.msg('上传失败,请重新上传'); } }); }); </script>

⒊ 后端处理

  • 因为前端默认的是 POST 请求,核心代码如下:
if ($_POST) {
    //上传图片具体操作
    $file_name = $_FILES['file']['name'];
    //$file_type = $_FILES["file"]["type"];
    $file_tmp = $_FILES["file"]["tmp_name"];
    $file_error = $_FILES["file"]["error"];
    $file_size = $_FILES["file"]["size"];

    if ($file_error > 0) { // 出错
        $message = $file_error;
    } elseif($file_size > 1048576) { // 文件太大了
        $message = "上传文件不能大于1MB";
    }else{
        $date = date('Ymd');
        $file_name_arr = explode('.',$file_name);
        $new_file_name = date('YmdHis') . '.' . $file_name_arr[1];
        $path = "upload/".$date."/";
        $file_path = $path . $new_file_name;
        if (file_exists($file_path)) {
            $message = "此文件已经存在啦";
        } else {
        //Todo 判断当前的目录是否存在,若不存在就新建一个!
        if (!is_dir($path)){mkdir($path,0777);}

            $upload_result = move_uploaded_file($file_tmp,$file_path); 
            //此函数只支持 HTTP POST 上传的文件
            if ($upload_result) {
                $status = 1;
                $message = $file_path;
            } else {
                $message = "文件上传失败,请稍后再尝试";
            }
        }
    }
} else {
    $message = "参数错误";
}
return showMsg($status,$message);
  • 补充公共函数 showMsg()
function showMsg($status,$message = '',$data = array()){
    $result = array(
        'status' => $status,'message' =>$message,'data' =>$data
    );
    exit(json_encode($result));
}

⒋ 实现效果

♬ 附录

⒈ 注意事项

  • 提供的代码,可用于PHP的原生开发或其他流行框架,其实只要后台能接收到 $_FILES 数据就好办了
  • 我就是卡在了 Laravel 框架的 CSRF 认证上,耗费了好多时间,所以:
<!--如果使用的是Laravel框架,打开下面这句话!-->
    <!--<input type="hidden" name="_token" class="tag_token" value="<?PHP /*echo csrf_token(); */?>">-->
  • 后端代码的图片上传功能属于原生程序,可自行优化,建议使用流行框架所推荐的集成方法。

⒉ 源码下载

  • 源码下载提供 >>>

⒊ 问题补充

对于上述的代码,需要注意一点 : move_uploaded_file()方法的使用

  • 如果图片所上传的目录不存在,很可能会报错,所以需要判断当前情况,若不存在,要建立新目录
//Todo 判断当前的目录是否存在,若不存在就新建一个!
if (!is_dir($path)){mkdir($path,0777);}
  • 注意上文中 【后端处理】 中的核心代码更新,使用下载文件时,可将此处的核心代码替换

Laravel+Layer 图片上传功能的更多相关文章

  1. 基于Html5 canvas实现裁剪图片和马赛克功能及又拍云上传图片 功能

    这篇文章主要介绍了基于Html5 canvas实现裁剪图片和马赛克功能及又拍云上传图片 功能,需要的朋友可以参考下

  2. 如何使用iOS SDK保存LinkedIn访问令牌?

    我在我的iOS应用程序中使用LinkedIn.我想保存访问令牌以供将来使用.令牌属于非属性类型,无法直接保存在NSUserDefaults中.我尝试使用NSKeyedArchiver,但我得到了输出:令牌中的文本即将到来,但值将为空.代码段1:我也尝试像这样保存,但结果是一样的:代码段2:我的编码或访问令牌有什么问题需要一些特殊技术来保存吗?请建议.解决方法这就是我拯救的方式.它对我有用.希望它有所帮助以这种方式使用保存的responseBody我希望这次我很清楚

  3. IOS Facebook身份验证使用node.js passport-facebook-token

    我正在尝试使用来自IOS应用程序的passport-facebook-token对node.jsapi进行身份验证.我有用户名和密码验证设置,并通过护照和护照-facebook-token设置正常工作.我只是无法弄清楚将访问令牌发送到API所需的HTTP请求语法.任何帮助都将受到大力赞赏.谢谢.解决方法确定设法从passport-facebook-token的策略文件中找出答案这个需要:http://URL?access_token=[访问令牌]从IOS我只是用以下方法测试:希望这有助于其他人.

  4. 解析条纹iOS main.js

    我真的很难让ParseStripe在我的项目中工作.此时,我想要最简单的工作版本,允许我向用户收费.我找到答案的最接近的事情如下:SimplestExampleI’veFound当我使用上面链接中的更正代码时,我的秘密得到以下错误:请帮助=**(这太令人沮丧了.————-更新—————-其他一些帖子也有类似的错误,看起来最新版本的ParseCloud代码应该归咎于:1.6.0.在控制台视图中使用以

  5. 基于Swift语言开发微信、QQ和微博的SSO授权登录代码分析

    一,总体架构1,引入第三方库除了必须引入对应的登录SDK外,额外引入了SDWebImage,SVProgressHUD,看名字大家都明白吧,引入登录SDK请各自看官方的开发文档,需要加入什么系统库文件,需要配置OtherLinkerFlags等,请参考各自官方文档即可;2,配置连接桥文件因为创建的工程是基于Swift语言,目前官方SDK和其它三方库都是用OC写的,所以为了在swift中调用oc代码

  6. swift开发笔记20 图片上传的最简单办法

    大概思路就是用base64编码把二进制图片转出字符串,通过简单的post请求发送到服务器,服务器端再反转成图片即可。首先把图片转为base64编码:图片变成字符串以后就是这样:服务器端接收:

  7. swift 上传图片和参数 upload image with params

    Alamofire.upload(urlRequest.0,urlRequest.1).progress{(bytesWritten,totalBytesWritten,totalBytesExpectedToWrite)inprintln("\(totalBytesWritten)/\(totalBytesExpectedToWrite)")}}

  8. 基于Swift语言开发微信、QQ跟微博的SSO授权登录代码分析

    转自:http://www.myexception.cn/swift/1991018.html前言Swift语言,怎么说呢,有一种先接受后排斥,又欢迎的感觉,纵观国外大牛开源框架或项目演示,Swift几乎占据了多半,而国内虽然出现很多相关技术介绍和教程,但是在真正项目开发中使用的占据很少部分,原因一是目前熟练它的开发者并不多,二是版本不太稳定,还需要更成熟可靠的版本支持,但总之未来还是很有前景的,

  9. swift3.0 上传图片旋转问题

  10. Swift3 单例模式

    常见的有这么几种方法第一种最简单也是最常用的,这里的所有单例init方法一定要定义成private的,不然外部依然可以使用init方法初始化变量。final关键字的作用是这个类或方法不希望被继承和重写第二种第二种完全是OC风格的单例,但是由于Swift3中废弃了原来的dispatch_once_t,所以需要先给dispatchQueue添加一个extension,实现原先的dispatch_once_t效果第三种第四种在方法内定义静态变量

随机推荐

  1. xe-ajax-mock 前端虚拟服务

    最新版本见Github,点击查看历史版本基于XEAjax扩展的Mock虚拟服务插件;对于前后端分离的开发模式,ajax+mock使前端不再依赖后端接口开发效率更高。CDN使用script方式安装,XEAjaxMock会定义为全局变量生产环境请使用xe-ajax-mock.min.js,更小的压缩版本,可以带来更快的速度体验。

  2. vue 使用 xe-ajax

    安装完成后自动挂载在vue实例this.$ajaxCDN安装使用script方式安装,VXEAjax会定义为全局变量生产环境请使用vxe-ajax.min.js,更小的压缩版本,可以带来更快的速度体验。cdnjs获取最新版本点击浏览已发布的所有npm包源码unpkg获取最新版本点击浏览已发布的所有npm包源码AMD安装require.js安装示例ES6Module安装通过Vue.use()来全局安装示例./Home.vue

  3. AJAX POST数据中文乱码解决

    前端使用encodeURI进行编码后台java.net.URLDecoder进行解码编解码工具

  4. Koa2框架利用CORS完成跨域ajax请求

    实现跨域ajax请求的方式有很多,其中一个是利用CORS,而这个方法关键是在服务器端进行配置。本文仅对能够完成正常跨域ajax响应的,最基本的配置进行说明。这样OPTIONS请求就能够通过了。至此为止,相当于仅仅完成了预检,还没发送真正的请求呢。

  5. form提交时,ajax上传文件并更新到&lt;input&gt;中的value字段

  6. ajax的cache作用

    filePath="+escape;},error:{alert;}});解决方案:1.加cache:false2.url加随机数正常代码:网上高人解读:cache的作用就是第一次请求完毕之后,如果再次去请求,可以直接从缓存里面读取而不是再到服务器端读取。

  7. 浅谈ajax上传文件属性contentType = false

    默认值为contentType="application/x-www-form-urlencoded".在默认情况下,内容编码类型满足大多数情况。在这里,我们主要谈谈contentType=false.在使用ajax上传文件时:在其中先封装了一个formData对象,然后使用post方法将文件传给服务器。说到这,我们发现在JQueryajax()方法中我们使contentType=false,这不是冲突了吗?这就是因为当我们在form标签中设置了enctype=“multipart/form-data”,

  8. 909422229_ajaxFileUpload上传文件

    ajaxFileUpload.js很多同名的,因为做出来一个很容易。我上github搜AjaxFileUpload出来很多类似js。ajaxFileUpload是一个异步上传文件的jQuery插件传一个不知道什么版本的上来,以后不用到处找了。语法:$.ajaxFileUploadoptions参数说明:1、url上传处理程序地址。2,fileElementId需要上传的文件域的ID,即的ID。3,secureuri是否启用安全提交,默认为false。4,dataType服务器返回的数据类型。6,error

  9. AJAX-Cache:一款好用的Ajax缓存插件

    原文链接AJAX-Cache是什么Ajax是前端开发必不可少的数据获取手段,在频繁的异步请求业务中,我们往往需要利用“缓存”提升界面响应速度,减少网络资源占用。AJAX-Cache是一款jQuery缓存插件,可以为$.ajax()方法扩展缓存功能。

  10. jsf – Ajax update/render在已渲染属性的组件上不起作用

    我试图ajax更新一个有条件渲染的组件。我可以确保#{user}实际上是可用的。这是怎么引起的,我该如何解决呢?必须始终在ajax可以重新呈现之前呈现组件。Ajax正在使用JavaScriptdocument.getElementById()来查找需要更新的组件。但是如果JSF没有将组件放在第一位,那么JavaScript找不到要更新的内容。解决方案是简单地引用总是渲染的父组件。

返回
顶部