# MailHog

向军大叔每晚八点在 抖音 (opens new window)bilibli (opens new window) 直播

xj-small

使用 MailHog (opens new window) 可以在本地进行邮件发送测试。

# 安装

homestead

建议使用homestead (opens new window) 过行本地开发,在 Homestead 内部已经安装了 MailHog (opens new window) ,所以可以直接使用。

valet

如果你使用 valet 时,请使用以下方式安装。

brew install mailhog
brew services start mailhog

# 配置

Laravel 中发送邮件是非常简单的,下面将 .env 配置文件定义为使用 MailHog (opens new window) 发送邮件。

MAIL_MAILER=smtp
MAIL_HOST=localhost
MAIL_PORT=1025
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
MAIL_FROM_ADDRESS="hello@example.com"
MAIL_FROM_NAME="${APP_NAME}"

# 使用

现在可以使用 laravel 来发送邮件了,然后在 localhost:8025 中查看。

image-20220318192442862

# 运行环境

如果相要在命令行和 HTTP 使用不同配置,使用$this->app->runningInConsole()可判断运行模式,下面是在命令行模式下设置app.name配置项。

if ($this->app->runningInConsole()) {
  config(['app.name' => '后盾人']);
}

根据配置文件APP_ENV 值来使用不同的配置项,在AppServiceProvider中定义以下代码,在 local 模式下开启 Telescope 扩展

if ($this->app->isLocal()) {
  $this->app->register(\Laravel\Telescope\TelescopeServiceProvider::class);
  $this->app->register(TelescopeServiceProvider::class);
  $this->app->register(\Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider::class);
}

# 优化

# 关闭 debug

修改.env 配置文件,并关闭 debug 调试模式

APP_DEBUG=false

# 缓存配置和路由

执行以下命令缓存配置与路由

php artisan route:cache
php artisan config:cache

执行以下命令可以清除缓存

php artisan cache:clear

# 优化自动加载

优化应用程序性能,生成自动加载文件,且产生聚合编译文件 bootstrap/compiled.php

php artisan optimize

执行以下命令即是上面命令的反操作

php artisan clear-compiled

# composer 优化

优化 composer 自动加载

composer dump-autoload --optimize

# 路由技巧

# 控制器调用路由

return \Route::respondWithRoute('edu.front.video.search');

# 资源路由别名前缀

Route::resource('lesson', 'LessonBuyController')->names('buy.lesson');

# 模板操作

# 自定义模板目录

有时需要自定义模板使用的目录,而不是使用默认提供的resources/views 目录,下面是添加视图加载目录templates

View::addLocation(base_path('templates'));

# 模板扩展名

Laravel 默认的模板文件后缀为 .blade.php 文件,我们也可以定义为其他扩展名

  • 以下代码将.html 定义为支持 blade 语法的模板
View::addExtension('html', 'blade');

使用 vscode 编辑器时需要将 html 文件的语言模式更改为 `blade'

image-20201114222915849

# 自定义 Blade 标签

app/Providers/AppServiceProvider.php 文件中定义

public function boot()
{
		\Blade::directive('category',function($expression){
         $php=<<<php
            <?php
    \$data = \Modules\Article\Entities\Category::whereIn('id',explode(',','$expression'))->get();
    foreach(\$data as \$field):
    ?>
php;
            return $php;
        });
        \Blade::directive('endcategory',function(){
            return "<?php endforeach;?>";
        });
}

上面我们定义了 categoryendcategory 两个标签用于遍历 Category 模型数据,使用方法如下:

@category(1,2)
        <li>{{$field['name']}}</li>
@endcategory

# 跨域请求

在使用 vite /vuecli 等构建工具开发时经常遇到,如后台为 api.houdunren.com,前台为 localhost:3000。

如果后台要使用cookie 进行权限验证。这时就需要前台可以传递 cookie,我们使用代理完成这个功能。

下面来开始进行操作

  • 首先将 axios 的 baseURL 设置为/api

  • 主要是配置 vite.config.js 的 server/proxy 代理完成,最终将实现通过 http://houdunren.test/api访问后台,通过代理实现同域请求

  • 如果最终生产环境前后台使用同域,那么后台不需要任何 cors 等配置

export default defineConfig({
  ...
  //开发环境设置
  server: {
      proxy: {
        '/sanctum': {
            //将/api访问转换为target
            target: 'http://houdunren.test/sanctum',
            changeOrigin: true,
            rewrite: path => path.replace(/^\/sanctum/, ''),
          },
         '/api': {
              //将/api访问转换为target
              target: 'http://houdunren.test/api',
              //跨域请求携带cookie
              changeOrigin: true,
              //url 重写删除`/api`
              rewrite: path => path.replace(/^\/api/, ''),
          },
      },
  },
})

# 使用 TOKEN

开启 cors

如果使用 laravel 框架开启 cors 跨域请求非常容易,其内部已经内置了cors处理。修改配置文件config/cors.php

return [
    'paths' => ['api/*', 'sanctum/csrf-cookie'],

    'allowed_methods' => ['*'],

    'allowed_origins' => ['*'],

    'allowed_origins_patterns' => [],

    'allowed_headers' => ['*'],

    'exposed_headers' => [],

    'max_age' => 0,

    'supports_credentials' => false,
];

cors 错误

不过要注意,如果在客户端存在 cookie(这可能是通过代理访问产生的)。但现在我们使用 token 验证,则需要将 cookie 全部删除,因为客户端会始终携带 cookie 请求后台,会产生 cors 错误,因为现在是不同的域名(不是同一顶级域)。

csrf 验证

如果后台是 laravel 需要在中间件 App\Http\Middleware\VerifyCsrfToken 中将api前缀路由排除 csrf 验证

protected $except = [
  'api/*'
];