首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

Yii2 控制器 AJAX 處理最佳實踐:JSON 回應、參數綁定、前端調用完整範例

     編輯:PHP 相關知識

Yii2 控制器 AJAX 處理最佳實踐:JSON 回應、參數綁定、前端調用完整範例

Yii2 內建支援 AJAX 請求檢測、JSON 格式化回應、參數自動綁定。本文提供控制器動作與前端 jQuery/Fetch 完整範例,涵蓋參數驗證、錯誤碼規範、CSRF 處理、回應結構統一。

控制器動作實作

<?php
namespace app\controllers;

use Yii;
use yii\web\Controller;
use yii\web\BadRequestHttpException;

class SupermarketsController extends Controller
{
    // 關閉該動作的 CSRF 驗證(API 介面通常用 Token 驗證)
    public function beforeAction($action) {
        if ($action->id === 'sample') {
            $this->enableCsrfValidation = false;
        }
        return parent::beforeAction($action);
    }

    public function actionSample() {
        $request = Yii::$app->request;

        // 僅接受 AJAX POST
        if (!$request->isAjax || !$request->isPost) {
            throw new BadRequestHttpException('僅支援 AJAX POST 請求');
        }

        // 參數獲取與驗證
        $searchName = $request->post('searchname', '');
        $searchBy = $request->post('searchby', '');

        if ($searchName === '') {
            return ['code' => 400, 'message' => '搜尋關鍵字不可為空', 'data' => null];
        }

        // 業務邏輯(示範)
        $results = $this->searchSupermarkets($searchName, $searchBy);

        // 統一 JSON 回應結構
        Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
        return [
            'code' => 200,
            'message' => 'success',
            'data' => [
                'list' => $results,
                'total' => count($results),
            ],
        ];
    }

    private function searchSupermarkets(string $keyword, string $type): array {
        // 實際應查詢資料庫/ES/Redis
        return [
            ['id' => 1, 'name' => '全聯福利中心 - ' . $keyword],
            ['id' => 2, 'name' => '家樂福 - ' . $keyword],
        ];
    }
}
?>

前端調用範例

jQuery 版

<script>
$('#searchBtn').on('click', function() {
    $.ajax({
        url: 'request->baseUrl ?>/supermarkets/sample',
        type: 'POST',
        dataType: 'json',
        data: {
            searchname: $('#searchname').val().trim(),
            searchby: $('#searchby').val()
        },
        beforeSend: function() {
            $('#loading').show();
        },
        success: function(res) {
            if (res.code === 200) {
                renderList(res.data.list);
            } else {
                alert(res.message);
            }
        },
        error: function(xhr) {
            alert('請求失敗:' + xhr.statusText);
        },
        complete: function() {
            $('#loading').hide();
        }
    });
});
</script>

Fetch API 版(現代瀏覽器)

<script>
async function search() {
    const btn = document.getElementById('searchBtn');
    btn.disabled = true;
    try {
        const res = await fetch('request->baseUrl ?>/supermarkets/sample', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded',
                'X-Requested-With': 'XMLHttpRequest' // 標識 AJAX
            },
            body: new URLSearchParams({
                searchname: document.getElementById('searchname').value.trim(),
                searchby: document.getElementById('searchby').value
            })
        });
        const data = await res.json();
        if (data.code === 200) {
            renderList(data.data.list);
        } else {
            alert(data.message);
        }
    } catch (e) {
        console.error(e);
        alert('網路錯誤');
    } finally {
        btn.disabled = false;
    }
}
</script>

關鍵最佳實踐總結

面向建議
請求檢測`$request->isAjax` + `$request->isPost` 雙重檢查
參數獲取`$request->post('key', 'default')` 安全取值,避免 Notice
驗證失敗回傳 400 碼 + 明確訊息,前端統一處理
回應格式統一 `{code, message, data}` 結構,`Response::FORMAT_JSON` 自動設 Header
CSRFAPI 介面關閉 CSRF,改用 JWT/ApiToken 驗證
錯誤處理拋 `BadRequestHttpException`/`ServerErrorHttpException` 讓錯誤處理器統一格式化
測試Postman/ curl 驗證非 AJAX 請求正確返回 400

進階:統一錯誤處理器

// config/main.php
'components' => [
    'errorHandler' => [
        'errorAction' => 'site/error',
    ],
],
// 控制器
public function actionError() {
    $exception = Yii::$app->errorHandler->exception;
    if ($exception) {
        Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
        return [
            'code' => $exception->statusCode ?? 500,
            'message' => $exception->getMessage(),
            'data' => null,
        ];
    }
}

延伸閱讀

更多 Yii2 RESTful API 開發、ActiveController、資源類、速率限制、驗證器複用、API 版本控制、Swagger/OpenAPI 文檔生成、單元測試與 Mock,請參考本站專題系列。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved