Flutter Web客户端日期时间验证及请求Header报错解决方案
问题原因
浏览器遵循XMLHttpRequest规范,Date属于禁止手动设置的不安全请求头,手动添加会被浏览器直接拦截,不会发送到服务端,这就是你看到"Refused to set unsafe header 'date'"错误的核心原因。
解决与实现方案
1. 改用自定义请求头传递时间戳
放弃使用标准Date头,换成自定义字段(比如X-Request-Timestamp),浏览器不会限制这类自定义头。Flutter Web的实现示例:
import 'package:http/http.dart' as http; Future<void> sendRequest() async { // 生成UTC标准格式时间戳,避免时区差异导致验证错误 final utcTimestamp = DateTime.now().toUtc().toIso8601String(); final response = await http.post( Uri.parse('你的服务端接口地址'), headers: { 'X-Request-Timestamp': utcTimestamp, // 其他业务所需头信息 }, body: {'param': 'value'}, ); }
2. 服务端验证逻辑
服务端拿到X-Request-Timestamp后执行以下步骤:
- 将时间戳转为UTC时间,与服务端当前UTC时间做差值对比
- 设定合理误差范围(比如5分钟),超过范围则判定请求无效,防止重放攻击
3. 可选:添加签名防止时间戳篡改
如果要避免客户端恶意篡改时间戳,可增加签名验证环节:
- 客户端用仅你和服务端知晓的共享密钥,对时间戳做HMAC加密生成签名
- 将时间戳和签名分别放在
X-Request-Timestamp和X-Request-Signature头中发送 - 服务端用相同密钥和时间戳重新计算签名,对比一致则验证通过
Flutter Web端签名示例(需引入crypto包):
import 'package:crypto/crypto.dart'; import 'dart:convert'; String generateHmacSignature(String timestamp, String secretKey) { final rawData = utf8.encode('$timestamp$secretKey'); final hmacSha256 = Hmac(sha256, utf8.encode(secretKey)); return hmacSha256.convert(rawData).toString(); } // 发送请求时 final utcTimestamp = DateTime.now().toUtc().toIso8601String(); final signature = generateHmacSignature(utcTimestamp, '你的共享密钥'); final response = await http.post( Uri.parse('你的服务端接口地址'), headers: { 'X-Request-Timestamp': utcTimestamp, 'X-Request-Signature': signature, }, );
内容的提问来源于stack exchange,提问作者l.diazborg
相关产品推荐
相关产品推荐

