[扩展推荐] Ziggy:在 JavaScript 中使用 Laravel 的命名路由

「译者注」 一句话来描述这个扩展的作用:可以解决在 JavaScript 中无法方便设置 URL 的问题。例如 question/{question}/edit 这种结构。

「译者注」 这篇文章虽然时间比较早,是2017年的了。但该扩展还是很实用的,而且也在一直更新,增加了一些新功能,比如白名单、黑名单等安全性相关更新,我会补充到文章末尾。

我的 JavaScript 中充满了 [axios] (https://github.com/mzabriskie/axios) 调用,这些调用是对 Laravel 应用中 API 接口地址的硬编码,当需要添加参数或者后端接口地址变更时会非常痛苦。

这就是为什么在 Laravel 中我们有 命名路由,以及为什么我们没有在 Blade 模板中硬编码 URL 的原因。通过抽象化我们的使用代码来了解路由的准确 URL 的需求,我们能够编写更多健壮性的代码-并避免了很多因为路由变更而导致的「查找和替换」。

我们希望在 JavaScript 中可以获得与 Laravel 应用程序相同的体验,这就是我们建造 Ziggy 的原因。

Basic Usage

安装 Ziggy

1、使用 Composer 进行安装: composer require tightenco/ziggy
2、如果你的 Laravel 版本小于 5.5,那么需要将Tightenco\Ziggy\ZiggyServiceProvider::class 添加到 config/app.php 文件的 providers 数组中。
3、在加载主应用程序 JavaScript 之前,将我们的自定义 Blade 指令 @routes 放到应用程序的 Blade 布局文件中,一般是放在 layout.blade.php 文件中。

layout.blade.php

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta name="csrf-token" content="{{ csrf_token() }}">
        <title>{{ config('app.name', 'Laravel') }}</title>
        <link rel="stylesheet" href="{{ mix('css/app.css') }}">
    </head>
    <body>
        <div class="app">
        </div>
        // 自定义 Blade 指令
        @routes
        <script src="{{ mix('js/app.js') }}"></script>
    </body>
</html>

Blade 指令将替换为 <script> 标签,在 Ziggy.namedRoutes 的 JavaScript 对象中,包含了路由信息。
该指令还包含一个名为 route() 的 JavaScript 方法,功能与 Laravel 的 route() 辅助方法非常相似。

routes/api.php

// 没有路由名称,所以不会输出在前端
Route::get('/', 'HomeController');

// 有路由名称,会输出在前端
Route::group(['as' => 'posts.'], function () {
    Route::get('/', 'PostsController@index')
        ->name('index');
    Route::get('/{post}', 'PostsController@show')
        ->name('show');
    Route::post('/', 'PostsController@store')
        ->name('store');
});

Route::get('/{post}/comments', 'PostCommentsController@index')
        ->name('post-comments.index');

这事 @routes 标签输出的实际代码(为了方便显示,只显示了一个路由信息):

JavaScript 内容

<script>
var namedRoutes = JSON.parse(
    '{"posts.index":{"uri":"posts","methods":["GET","HEAD"]}}'
);
// 可以在下面使用 route() 方法来获取 URL
</script>

就如你看到的一样,我们增加了 window.namedRoutes 对象,可以随时访问它。它是一个包含一系列数据的对象,其中包括路由名称、提交方法等,它使用路由的名称作为键值,因此可以直接在代码中这么使用:
var routeObject = window.namedRoutes['posts.index'];

当然,推荐你使用 route() 辅助方法,它与 Laravel 框架的 route() 作用非常相似,会更加方便:

// 实际值为: /posts
var routeUrl = route('posts.index');
// 实际值为:/posts/1337
var routeUrl = route('posts.show', {post: 1337});

这是背后运行的真实样子:

// Returns results from /posts
return axios.get(route('posts.index'))
    .then((response) => {
        return response.data;
    });

// Returns results from /posts/1
return axios.get(route('posts.show', {post: postId}))
    .then((response) => {
        return response.data;
    });

route() 辅助方法有 2 个参数

  • 路由名称(必填)
  • 路由参数(可选)

例如 posts.show 路由信息需要一个 post 参数,因为我们将 {post: postId} 作为参数传递给 route() 辅助方法。

结论

将 Ziggy 扩展包引入 Laravel 并将 @routes 指令放入全局模板后,你将考验使用 route() 辅助方法,它与 Laravel 的辅助方法一样方便。最重要的是这将 Laravel 的路由信息与 JavaScript 代码关联起来了,避免了因为修改路由信息而批量查找、替换 JavaScript 代码的情况。

「译者注」 目前最新的扩展包已经支持了对路由信息进行过滤的功能,可以设置黑名单或白名单的方式,提升了一定的安全性,我可不想把项目的所有路由信息暴露给你看。

如何过滤路由信息

默认会将所有信息都输出在前端,如果想控制路由信息的显示,可以使用白名单或者黑名单的方式:

  • 在 config 目录下新建 ziggy.php 文件
  • 设置 whitelist 或 blacklist 数组
<?php
return [
    // 'whitelist' => ['home', 'api.*'],
    'blacklist' => ['debugbar.*', 'admin.*'],
];

为了安全性,对 admin 以及 debugbar 相关的路由信息屏蔽输出,这样前端的 JavaScript 数组中就看不到,当然你也无法在 JavaScript 中使用 route() 辅助方法了。
还可以有其他的设置方式,具体可以取项目主页瞧一下。

本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。

原文地址:https://tighten.co/blog/ziggy-laravel-na...

译文地址:https://learnku.com/laravel/t/40992

本文为协同翻译文章,如您发现瑕疵请点击「改进」按钮提交优化建议
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
讨论数量: 2

nice,解决了长久以来的痛点

1年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!