ThinkPHP Ajax 請求處理:ajaxReturn() 方法用法、JSON 回傳與前端對接完整指南
ThinkPHP 內建 ajaxReturn() 方法簡化 Ajax 回應處理,支援 JSON、XML、Eval 等多種格式。本文詳細說明方法參數、前端 jQuery 對接、錯誤碼規範與最佳實踐。
ajaxReturn() 方法語法
$this->ajaxReturn(mixed $data, string $type = 'JSON', int $ajax = 1)
| 參數 | 說明 | 預設值 |
$data | 要回傳的資料(陣列、物件、字串) | 必填 |
$type | 回傳格式:JSON、XML、JSONP、EVAL | JSON |
$ajax | 是否為 Ajax 請求(影響輸出方式) | 1 |
基本用法範例
控制器端
<?php
class ApiController extends Controller {
public function login() {
$username = I('post.username');
$password = I('post.password');
// 驗證邏輯...
if ($user = D('User')->verify($username, $password)) {
$this->ajaxReturn([
'status' => 1,
'msg' => '登入成功',
'data' => ['uid' => $user['id'], 'token' => generateToken()]
], 'JSON');
} else {
$this->ajaxReturn([
'status' => 0,
'msg' => '帳號或密碼錯誤',
'data' => null
], 'JSON');
}
}
public function getList() {
$list = M('Article')->select();
$this->ajaxReturn($list, 'JSON'); // 直接回傳陣列
}
}
前端 jQuery 對接
<script>
$.post('/api/login', {
username: $('#username').val(),
password: $('#password').val()
}, function(response) {
// response 為 JSON 物件
if (response.status === 1) {
alert(response.msg);
localStorage.setItem('token', response.data.token);
window.location.href = '/dashboard';
} else {
alert('錯誤:' + response.msg);
}
}, 'json'); // 指定期望 JSON 回應
</script>
支援的回傳格式
| 類型 | Content-Type | 用途 | 範例 |
| JSON | application/json | 標準 API 回應 | {"status":1,"data":[]} |
| XML | text/xml | 舊系統整合 | <root><status>1</status></root> |
| JSONP | application/javascript | 跨域請求 | callback({"status":1}) |
| EVAL | text/html | 直接執行 JS 代碼 | alert('ok'); |
JSONP 跨域範例
<?php
// 控制器
public function jsonpDemo() {
$data = ['time' => time(), 'rand' => mt_rand()];
// 獲取回調函數名(通常為 callback 參數)
$callback = I('get.callback', 'callback');
$this->ajaxReturn($data, 'JSONP', $callback);
}
// 前端
$.ajax({
url: '/api/jsonpDemo',
dataType: 'jsonp', // jQuery 自動處理 callback 參數
success: function(data) {
console.log('伺服器時間:', data.time);
}
});
統一回應格式規範(建議)
<?php
// 基類控制器封裝
class BaseApiController extends Controller {
protected function success($data = [], $msg = '成功') {
$this->ajaxReturn([
'code' => 200,
'status' => true,
'message' => $msg,
'data' => $data,
'timestamp' => time(),
], 'JSON');
}
protected function error($msg = '失敗', $code = 400, $data = []) {
$this->ajaxReturn([
'code' => $code,
'status' => false,
'message' => $msg,
'data' => $data,
'timestamp' => time(),
], 'JSON');
}
protected function validateError($validator) {
$this->error('驗證失敗:' . $validator->getError(), 422);
}
}
// 使用
class UserController extends BaseApiController {
public function login() {
// 驗證...
if ($success) {
$this->success(['token' => $token], '登入成功');
} else {
$this->error('帳號或密碼錯誤');
}
}
}
常見問題與解決
| 問題 | 原因 | 解決 |
| 回傳中文亂碼 | JSON 編碼預設 Unicode 轉義 | PHP 5.4+ 用 JSON_UNESCAPED_UNICODE 或手動 json_encode($data, JSON_UNESCAPED_UNICODE) |
| 前端收到字串非物件 | 未指定 dataType: 'json' | jQuery $.post 最後參數設 'json' 或用 $.ajax 設 dataType |
| ajaxReturn 後仍執行程式碼 | ajaxReturn 不會終止腳本 | 呼叫後加 exit; 或 return |
| HTTP 狀態碼非 200 | ajaxReturn 預設 200 OK | 需自行 header('HTTP/1.1 401 Unauthorized') |
進階:API 版本控制與簽名驗證
<?php
class ApiController extends Controller {
public function _initialize() {
// 版本檢查
$version = I('get.v', '1.0');
if (!in_array($version, ['1.0', '2.0'])) {
$this->error('不支援的 API 版本', 400);
exit;
}
// 簽名驗證(簡化版)
$sign = I('get.sign');
$params = $_GET;
unset($params['sign']);
ksort($params);
$expected = md5(http_build_query($params) . C('API_SECRET'));
if ($sign !== $expected) {
$this->error('簽名驗證失敗', 401);
exit;
}
}
}