
本文详解如何使用 Flutter 的 http 包向 PHP MVC 网站(如登录接口 /login/checkuser)提交用户名与密码,并正确解析响应、处理会话与错误反馈。
本文详解如何使用 flutter 的 `http` 包向 php mvc 网站(如登录接口 `/login/checkuser`)提交用户名与密码,并正确解析响应、处理会话与错误反馈。
在 Flutter 中调用 PHP MVC 后端的登录接口,关键在于请求格式匹配、响应结构统一、错误可追溯。你当前的 PHP 代码直接输出 <script></script> 标签到 HTML 流中(如 echo '<script>console.log(...)</script>'),这不适合 API 场景——Flutter 期望接收标准 JSON 响应,而非混合 HTML/JS 的前端调试输出。
✅ 正确的前后端协作方式
首先,修改 PHP 后端(控制器 checkuser()),使其返回纯 JSON,而非脚本片段:
function checkuser()
{
$form = $_POST;
$error = $this->model->checkUser($form);
Model::sessionInit();
$userId = Model::sessionGet('userId');
// 统一 JSON 响应结构
$response = ['success' => false, 'message' => '', 'data' => null];
if ($userId !== false) {
$response['success'] = true;
$response['message'] = 'Login successful';
$response['data'] = ['userId' => (int)$userId];
} else {
$response['message'] = $error ?: 'Invalid username or password';
}
// 关键:设置 Content-Type 并输出 JSON
header('Content-Type: application/json; charset=utf-8');
echo json_encode($response);
exit;
}
? 注意:
exit防止后续输出干扰 JSON;json_encode()自动处理空值与编码;避免任何echo非 JSON 内容(如<script></script>)。
同时,确保你的 PHP 模型 checkUser() 仅返回字符串错误信息(当前逻辑已符合),但建议增强安全性:
- ✅ 使用
password_verify()替代明文密码比对(当前 SQL 直接查password=?存在严重安全隐患); - ✅ 对输入进行
trim()和filter_var($email, FILTER_SANITIZE_EMAIL)处理; - ✅ 开启 CORS(开发阶段可在 PHP 头部添加):
header('Access-Control-Allow-Origin: *'); header('Access-Control-Allow-Methods: POST'); header('Access-Control-Allow-Headers: Content-Type');
? Flutter 端:结构化请求与健壮解析
使用 http 包发送 application/x-www-form-urlencoded(更适配传统 PHP $_POST)或 application/json。推荐前者以兼容现有 PHP 表单逻辑:
import 'package:http/http.dart' as http;
import 'dart:convert';
Future<map dynamic>?> userLogin(String username, String password) async {
final url = Uri.parse('https://your-domain.com/login/checkuser'); // 替换为真实域名
final body = {
'username': username.trim(),
'password': password.trim(),
'remember': 'on', // 若需“记住我”,按需传 'on' 或 ''
};
try {
final response = await http.post(
url,
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
body: body, // 自动 URL 编码,无需 json.encode
);
if (response.statusCode == 200) {
final data = jsonDecode(response.body);
if (data is Map<string dynamic>) {
return data;
} else {
throw Exception('Invalid JSON response format');
}
} else {
throw Exception('HTTP ${response.statusCode}: ${response.statusMessage}');
}
} on http.ClientException catch (e) {
print('Network error: $e');
return null;
} on FormatException catch (e) {
print('JSON parse error: $e');
return null;
}
}</string></map>
? 调用示例(如在登录按钮 onPressed 中)
onPressed: () async {
final result = await userLogin(_usernameController.text, _passwordController.text);
if (result != null) {
if (result['success'] == true) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Welcome! User ID: ${result['data']['userId']}')),
);
// ✅ 导航至用户面板,如 Navigator.pushReplacement(...)
} else {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Error: ${result['message']}')),
);
}
}
},
⚠️ 重要注意事项
-
不要在生产环境暴露
remembercookie 设置逻辑给客户端:setcookie()是服务端行为,Flutter 无法直接读取 PHP 设置的 Cookie;如需持久化登录,请改用 Token(如 JWT)机制。 - HTTPS 强制要求:明文传输密码必须使用 HTTPS,否则存在中间人风险。
-
PHP 端启用
json_last_error()检查编码失败,避免空响应。 - Flutter 中
http.post()默认超时约 30 秒,如需自定义,使用http.Client配置BaseClient。
通过以上改造,你的 Flutter 应用即可稳定、安全、可维护地与 PHP MVC 后端交互——核心原则是:后端专供 API,前端专注消费 JSON。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











