Laravel 错误的路由重定向导致 404
Laravel wrong route redirection resulting in a 404
在我的 Laravel 应用程序中,我收到 404 错误,我无法弄清楚原因。该路线正确显示在 artisan route:list
中。我正在使用路由分组和前缀。 Laravel 调试输出显示与预期不同的 URI。 books.archives
路由似乎重定向到 book.display
路由。我只是不明白。
这是我的 web.php 的摘录:
// Books
Route::prefix('books')->name('books')->group(function() {
Route::get('/', [BooksController::class, 'list']);
Route::get('/create', [BooksController::class, 'create'])->name('.create');
Route::post('/', [BooksController::class, 'store'])->name('.store');
Route::get('/edit/{bookInfo}', [BooksController::class, 'edit'])->name('.edit');
Route::patch('/edit/{bookInfo}', [BooksController::class, 'update'])->name('.update');
Route::get('/{bookInfo}', [BooksController::class, 'display'])->name('.display');
Route::post('/delete/{id}', [BooksController::class, 'delete'])->name('.delete');
Route::prefix('archives')->name('.archives')->group(function() {
Route::get('/', [BooksController::class, 'archived']);
Route::get('/{bookInfo}', [BooksController::class, 'archive'])->name('.store');
Route::post('/delete/{bookInfo}', [BooksController::class, 'delete'])->name('.delete');
Route::post('/delete/all', [BooksController::class, 'deleteAll'])->name('.delete.all');
Route::get('/restore/{id}', [BooksController::class, 'restore'])->name('.restore');
});
});
artisan route:list
输出:
| | GET|HEAD | dashboard/books | books | App\Http\Controllers\BooksController@list | web |
| | | | | | App\Http\Middleware\Authenticate |
| | POST | dashboard/books | books.store | App\Http\Controllers\BooksController@store | web |
| | | | | | App\Http\Middleware\Authenticate |
| | GET|HEAD | dashboard/books/archives | books.archives | App\Http\Controllers\BooksController@archived | web |
| | | | | | App\Http\Middleware\Authenticate |
| | POST | dashboard/books/archives/delete/all | books.archives.delete.all | App\Http\Controllers\BooksController@deleteAll | web |
| | | | | | App\Http\Middleware\Authenticate |
| | POST | dashboard/books/archives/delete/{bookInfo} | books.archives.delete | App\Http\Controllers\BooksController@delete | web |
| | | | | | App\Http\Middleware\Authenticate |
| | GET|HEAD | dashboard/books/archives/restore/{id} | books.archives.restore | App\Http\Controllers\BooksController@restore | web |
| | | | | | App\Http\Middleware\Authenticate |
| | GET|HEAD | dashboard/books/archives/{bookInfo} | books.archives.store | App\Http\Controllers\BooksController@archive | web |
| | | | | | App\Http\Middleware\Authenticate |
| | GET|HEAD | dashboard/books/create | books.create | App\Http\Controllers\BooksController@create | web |
| | | | | | App\Http\Middleware\Authenticate |
| | POST | dashboard/books/delete/{id} | books.delete | App\Http\Controllers\BooksController@delete | web |
| | | | | | App\Http\Middleware\Authenticate |
| | GET|HEAD | dashboard/books/edit/{bookInfo} | books.edit | App\Http\Controllers\BooksController@edit | web |
| | | | | | App\Http\Middleware\Authenticate |
| | PATCH | dashboard/books/edit/{bookInfo} | books.update | App\Http\Controllers\BooksController@update | web |
| | | | | | App\Http\Middleware\Authenticate |
| | DELETE | dashboard/books/variations/delete/{book} | variations.delete | App\Http\Controllers\VariationsController@delete | web |
| | | | | | App\Http\Middleware\Authenticate |
| | GET|HEAD | dashboard/books/variations/edit/{book} | variations.edit | App\Http\Controllers\VariationsController@edit | web |
| | | | | | App\Http\Middleware\Authenticate |
| | PATCH | dashboard/books/variations/edit/{book} | variations.update | App\Http\Controllers\VariationsController@update | web |
| | | | | | App\Http\Middleware\Authenticate |
| | POST | dashboard/books/variations/{bookInfo}/add | variations.store | App\Http\Controllers\VariationsController@store | web |
| | | | | | App\Http\Middleware\Authenticate |
| | GET|HEAD | dashboard/books/variations/{bookInfo}/add | variations.create | App\Http\Controllers\VariationsController@create | web |
| | | | | | App\Http\Middleware\Authenticate |
| | GET|HEAD | dashboard/books/{bookInfo} | books.display | App\Http\Controllers\BooksController@display | web |
| | | | | | App\Http\Middleware\Authenticate |
控制器:
public function archived() {
$bookInfos = BookInfo::onlyTrashed()->get();
$archived = $bookInfos->count();
return view('books.archived', compact('bookInfos', 'archived'));
}
调试输出(来自页面/dashboard/books/archives):
我做错了什么?
由于路径同时匹配“books.display”和“books.archives.archived”路由,所以它可能会选择其中的第一个。尝试将“archive”组路由放在“book”路由之前:
// Books
Route::prefix('books')->name('books')->group(function() {
Route::prefix('archives')->name('.archives')->group(function() {
Route::get('/', [BooksController::class, 'archived']);
Route::get('/{bookInfo}', [BooksController::class, 'archive'])->name('.store');
Route::post('/delete/{bookInfo}', [BooksController::class, 'delete'])->name('.delete');
Route::post('/delete/all', [BooksController::class, 'deleteAll'])->name('.delete.all');
Route::get('/restore/{id}', [BooksController::class, 'restore'])->name('.restore');
});
Route::get('/', [BooksController::class, 'list']);
Route::get('/create', [BooksController::class, 'create'])->name('.create');
Route::post('/', [BooksController::class, 'store'])->name('.store');
Route::get('/edit/{bookInfo}', [BooksController::class, 'edit'])->name('.edit');
Route::patch('/edit/{bookInfo}', [BooksController::class, 'update'])->name('.update');
Route::get('/{bookInfo}', [BooksController::class, 'display'])->name('.display');
Route::post('/delete/{id}', [BooksController::class, 'delete'])->name('.delete');
});
在我的 Laravel 应用程序中,我收到 404 错误,我无法弄清楚原因。该路线正确显示在 artisan route:list
中。我正在使用路由分组和前缀。 Laravel 调试输出显示与预期不同的 URI。 books.archives
路由似乎重定向到 book.display
路由。我只是不明白。
这是我的 web.php 的摘录:
// Books
Route::prefix('books')->name('books')->group(function() {
Route::get('/', [BooksController::class, 'list']);
Route::get('/create', [BooksController::class, 'create'])->name('.create');
Route::post('/', [BooksController::class, 'store'])->name('.store');
Route::get('/edit/{bookInfo}', [BooksController::class, 'edit'])->name('.edit');
Route::patch('/edit/{bookInfo}', [BooksController::class, 'update'])->name('.update');
Route::get('/{bookInfo}', [BooksController::class, 'display'])->name('.display');
Route::post('/delete/{id}', [BooksController::class, 'delete'])->name('.delete');
Route::prefix('archives')->name('.archives')->group(function() {
Route::get('/', [BooksController::class, 'archived']);
Route::get('/{bookInfo}', [BooksController::class, 'archive'])->name('.store');
Route::post('/delete/{bookInfo}', [BooksController::class, 'delete'])->name('.delete');
Route::post('/delete/all', [BooksController::class, 'deleteAll'])->name('.delete.all');
Route::get('/restore/{id}', [BooksController::class, 'restore'])->name('.restore');
});
});
artisan route:list
输出:
| | GET|HEAD | dashboard/books | books | App\Http\Controllers\BooksController@list | web |
| | | | | | App\Http\Middleware\Authenticate |
| | POST | dashboard/books | books.store | App\Http\Controllers\BooksController@store | web |
| | | | | | App\Http\Middleware\Authenticate |
| | GET|HEAD | dashboard/books/archives | books.archives | App\Http\Controllers\BooksController@archived | web |
| | | | | | App\Http\Middleware\Authenticate |
| | POST | dashboard/books/archives/delete/all | books.archives.delete.all | App\Http\Controllers\BooksController@deleteAll | web |
| | | | | | App\Http\Middleware\Authenticate |
| | POST | dashboard/books/archives/delete/{bookInfo} | books.archives.delete | App\Http\Controllers\BooksController@delete | web |
| | | | | | App\Http\Middleware\Authenticate |
| | GET|HEAD | dashboard/books/archives/restore/{id} | books.archives.restore | App\Http\Controllers\BooksController@restore | web |
| | | | | | App\Http\Middleware\Authenticate |
| | GET|HEAD | dashboard/books/archives/{bookInfo} | books.archives.store | App\Http\Controllers\BooksController@archive | web |
| | | | | | App\Http\Middleware\Authenticate |
| | GET|HEAD | dashboard/books/create | books.create | App\Http\Controllers\BooksController@create | web |
| | | | | | App\Http\Middleware\Authenticate |
| | POST | dashboard/books/delete/{id} | books.delete | App\Http\Controllers\BooksController@delete | web |
| | | | | | App\Http\Middleware\Authenticate |
| | GET|HEAD | dashboard/books/edit/{bookInfo} | books.edit | App\Http\Controllers\BooksController@edit | web |
| | | | | | App\Http\Middleware\Authenticate |
| | PATCH | dashboard/books/edit/{bookInfo} | books.update | App\Http\Controllers\BooksController@update | web |
| | | | | | App\Http\Middleware\Authenticate |
| | DELETE | dashboard/books/variations/delete/{book} | variations.delete | App\Http\Controllers\VariationsController@delete | web |
| | | | | | App\Http\Middleware\Authenticate |
| | GET|HEAD | dashboard/books/variations/edit/{book} | variations.edit | App\Http\Controllers\VariationsController@edit | web |
| | | | | | App\Http\Middleware\Authenticate |
| | PATCH | dashboard/books/variations/edit/{book} | variations.update | App\Http\Controllers\VariationsController@update | web |
| | | | | | App\Http\Middleware\Authenticate |
| | POST | dashboard/books/variations/{bookInfo}/add | variations.store | App\Http\Controllers\VariationsController@store | web |
| | | | | | App\Http\Middleware\Authenticate |
| | GET|HEAD | dashboard/books/variations/{bookInfo}/add | variations.create | App\Http\Controllers\VariationsController@create | web |
| | | | | | App\Http\Middleware\Authenticate |
| | GET|HEAD | dashboard/books/{bookInfo} | books.display | App\Http\Controllers\BooksController@display | web |
| | | | | | App\Http\Middleware\Authenticate |
控制器:
public function archived() {
$bookInfos = BookInfo::onlyTrashed()->get();
$archived = $bookInfos->count();
return view('books.archived', compact('bookInfos', 'archived'));
}
调试输出(来自页面/dashboard/books/archives):
我做错了什么?
由于路径同时匹配“books.display”和“books.archives.archived”路由,所以它可能会选择其中的第一个。尝试将“archive”组路由放在“book”路由之前:
// Books
Route::prefix('books')->name('books')->group(function() {
Route::prefix('archives')->name('.archives')->group(function() {
Route::get('/', [BooksController::class, 'archived']);
Route::get('/{bookInfo}', [BooksController::class, 'archive'])->name('.store');
Route::post('/delete/{bookInfo}', [BooksController::class, 'delete'])->name('.delete');
Route::post('/delete/all', [BooksController::class, 'deleteAll'])->name('.delete.all');
Route::get('/restore/{id}', [BooksController::class, 'restore'])->name('.restore');
});
Route::get('/', [BooksController::class, 'list']);
Route::get('/create', [BooksController::class, 'create'])->name('.create');
Route::post('/', [BooksController::class, 'store'])->name('.store');
Route::get('/edit/{bookInfo}', [BooksController::class, 'edit'])->name('.edit');
Route::patch('/edit/{bookInfo}', [BooksController::class, 'update'])->name('.update');
Route::get('/{bookInfo}', [BooksController::class, 'display'])->name('.display');
Route::post('/delete/{id}', [BooksController::class, 'delete'])->name('.delete');
});