通过表单提交数据,并使用Session暂存数据实现提示和csrf_field

3780次阅读 253人点赞 作者: WuBin 发布时间: 2021-07-26 17:04:17
扫码到手机查看

Request::getPathInfo()实现焦点样式

<a href="{{ url('student/index') }}" class="list-group-item
{{ Request::getPathInfo() == '/student/index' ? 'active': '' }}
" data-request="{{Request::getPathInfo()}}">
    学生列表
</a>
<a href="{{ url('student/create')  }}" class="list-group-item
{{ Request::getPathInfo() == '/student/create' ? 'active' : '' }}
">
    新增学生
</a>

运行以上代码,我们可以看到最终结果:

Request::getPathInfo() 获取路由名称 用于对比路由是否需要加上active样式,注意得到的结果前面有个斜线“/”,所以对比路由的时候也要加上斜线!

url是通过路由名称生成访问地址,具体请见《Blade模板中的URL获取》

在模板中使用Request和Session,直接使用即可。

提交数据的两种方式

使用指定的路由地址提交

HTML(在面向对象中,都以模型的名字作为数组的key)案例中的模型名字是app/Student.php,所以使用模型名字Student:

<form class="form-horizontal" method="post" action="{{ url('student/save') }}">
    <input type="text" id="name" name="Student[name]" placeholder="请输入学生姓名">
    <input type="text" id="age" name="Student[age]" placeholder="请输入学生年龄">

    <input type="radio" name="Student[sex]" value="10">未知
    <input type="radio" name="Student[sex]" value="20">男
    <input type="radio" name="Student[sex]" value="30">女
</form>

新建一个路由:

Route::any('student/save', [
    'uses' => 'StudentController@save'
]);

在控制器中新建save方法,并书写代码:

public function save(Request $request)
{
    // 获取所有以Student为下标的数组数据
    // <input  name="Student[name]" name="Student[age]"
    // 最终得到array(3) { ["name"]=> string(3) "asd" ["age"]=> string(3) "sad" ["sex"]=> string(2) "20" }
    $data = $request->input('Student');
    // 实例化一个模型 并且设置值执行save方法进行保存到数据库
    $student = new Student();
    $student->name = $data['name'];
    $student->age = $data['age'];
    $student->sex = $data['sex'];

    // 如果成功
    if ($student->save()) {
        // 跳转到指定页面
        return redirect('student/index');
    } else {
        // 失败返回上一个请求页面
        return redirect()->back();
    }
}

注意这个Request 是 Illuminate\Http\Request获取一个$request实例,所以要在脚本开始位置使用:

// 使用请求参数的save方法中request需要使用Illuminate\Http\Request
use Illuminate\Http\Request;

使用当前页面进行提交

比如2.1中的HTML,是通过student/create方法进行渲染的:

public function create(Request $request)
{
    // 之后逻辑代码写在此处
    return view('student.create');
}
<form class="form-horizontal" method="post" action="">...</form>

action=""不填写,默认会提交到student/create这个路由对应的方法中,路由:

Route::any('student/create', [
    'uses' => 'StudentController@create'
]);

再在控制器中书写逻辑(正常都是get请求,只有提交是post请求,所以只要判断请求的类型即可):

if ($request->isMethod('post')) {
    $data = $request->input('Student');
    // 使用模型的::create方法会批量赋值,修改Student中的$fillable属性
    if (Student::create($data)) {
        // 比如成功或者失败提示,用到session的暂存数据,所以要加入到中间件中
        // with(key, 信息) 暂存数据只在第一次请求的时候生效
        return redirect('student/index')->with('success', '添加成功');
    } else {
        // 失败返回上一个请求页面
        return redirect()->back();
    }
}
return view('student.create');
$request->isMethod('post') 可以判断请求的类型。

在模板中读取Session

详情请参见我的另一篇文章:《控制器之Session》

web中间件从laravel 5.2.27版本以后默认全局加载,不需要自己手动载入,如果自己手动重复载入,会导致session无法加载的情况!!参考链接

所以不要将路由写在中间件之中,会导致session不可用!如下写法是错误的!

// 是错误的!这样写会导致session不可用,直接在routes.php中书写即可!
Route::group(['middleware' => ['web']], function () {
    Route::get('student/index', [
        'uses' => 'StudentController@index'
    ]);
    Route::any('student/create', [
        'uses' => 'StudentController@create'
    ]);
    Route::any('student/save', [
        'uses' => 'StudentController@save'
    ]);
});

当使用->with()传递暂存值之后,在模板中:

<!-- 成功提示框 -->
{{--如果session中有success这个值就让他显示,
使用has判断 5.2以后web中间件都是自动加载的 不需要在手动引用了,否则会导致session不可用--}}
@if(Session::has('success'))
    <div class="alert alert-success alert-dismissible">
        <!-- 操作成功提示 -->
        {{ Session::get('success') }}
    </div>
@endif
<!-- 失败提示框 -->
@if(Session::has('error'))
    <div class="alert alert-danger alert-dismissible">
        <!-- 操作失败提示 -->
        {{ Session::get('error') }}
    </div>
@endif

csrf_field()防止XSS攻击CSRF

Laravel框架中有此要求:任何指向 web 中 POST, PUT 或 DELETE 路由的 HTML 表单请求都应该包含一个 CSRF 令牌(CSRF token),否则,这个请求将会被拒绝。可以参考链接:https://blog.csdn.net/cnwyt/article/details/79540396

如果出现报错:报错TokenMismatchException in VerifyCsrfToken.php line 67 如下:

那么,解决这个错误的方法就是在表单中插入一个{{ csrf_field() }},如下:

<form class="form-horizontal" method="post" action="">
    {{ csrf_field() }}
    <div class="form-group">...</div>
    ...
</form>

csrf_field() 会生成一个隐藏的input表单,里面带一个token字段防止xss攻击(即是csrf)。不加的话提交表单会报错,这里十分重要,请谨记。

相关资料

点赞 支持一下 觉得不错?客官您就稍微鼓励一下吧!
关键词:csrf_field,Request::getPathInfo
推荐阅读
  • uniapp实现被浏览器唤起的功能

    当用户打开h5链接时候,点击打开app若用户在已经安装过app的情况下直接打开app,若未安装过跳到应用市场下载安装这个功能在实现上主要分为两种场景,从普通浏览器唤醒以及从微信唤醒。

    9119次阅读 589人点赞 发布时间: 2022-12-14 16:34:53 立即查看
  • Vue

    盘点Vue2和Vue3的10种组件通信方式

    Vue中组件通信方式有很多,其中Vue2和Vue3实现起来也会有很多差异;本文将通过选项式API组合式API以及setup三种不同实现方式全面介绍Vue2和Vue3的组件通信方式。

    3884次阅读 289人点赞 发布时间: 2022-08-19 09:40:16 立即查看
  • JS

    几个高级前端常用的API

    推荐4个前端开发中常用的高端API,分别是MutationObserver、IntersectionObserver、getComputedstyle、getBoundingClientRect、requ...

    14139次阅读 919人点赞 发布时间: 2021-11-11 09:39:54 立即查看
  • PHP

    【正则】一些常用的正则表达式总结

    在日常开发中,正则表达式是非常有用的,正则表达式在每个语言中都是可以使用的,他就跟JSON一样,是通用的。了解一些常用的正则表达式,能大大提高你的工作效率。

    12947次阅读 445人点赞 发布时间: 2021-10-09 15:58:58 立即查看
  • 【中文】免费可商用字体下载与考证

    65款免费、可商用、无任何限制中文字体打包下载,这些字体都是经过长期验证,经得住市场考验的,让您规避被无良厂商起诉的风险。

    11539次阅读 926人点赞 发布时间: 2021-07-05 15:28:45 立即查看
  • Vue

    Vue3开发一个v-loading的自定义指令

    在vue3中实现一个自定义的指令,有助于我们简化开发,简化复用,通过一个指令的调用即可实现一些可高度复用的交互。

    15646次阅读 1248人点赞 发布时间: 2021-07-02 15:58:35 立即查看
  • JS

    关于手机上滚动穿透问题的解决

    当页面出现浮层的时候,滑动浮层的内容,正常情况下预期应该是浮层下边的内容不会滚动;然而事实并非如此。在PC上使用css即可解决,但是在手机端,情况就变的比较复杂,就需要禁止触摸事件才可以。

    14843次阅读 1209人点赞 发布时间: 2021-05-31 09:25:50 立即查看
  • Vue

    Vue+html2canvas截图空白的问题

    在使用vue做信网单页专题时,有海报生成的功能,这里推荐2个插件:一个是html2canvas,构造好DOM然后转canvas进行截图;另外使用vue-canvas-poster(这个截止到2021年3月...

    29040次阅读 2281人点赞 发布时间: 2021-03-02 09:04:51 立即查看
  • Vue

    vue-router4过度动画无效解决方案

    在初次使用vue3+vue-router4时候,先后遇到了过度动画transition进入和退出分别无效的情况,搜遍百度没没找到合适解决方法,包括vue-route4有一些API都进行了变化,以前的一些操...

    25064次阅读 1931人点赞 发布时间: 2021-02-23 13:37:20 立即查看
交流 收藏 目录