Flutter Web调用Google Cloud Function POST接口持续返回415错误问题求助
我来帮你分析下这个415(Unsupported Media Type)错误的问题,结合你提供的代码和信息来看,既然curl能正常调用成功,说明Cloud Function本身的配置和逻辑是没问题的,问题大概率出在Flutter Web发送请求的细节上,下面给你几个排查方向和解决方案:
1. 确认Flutter Web实际发送的请求头
虽然你在代码里设置了'content-type': 'application/json',但Flutter Web在Web环境下发送请求时,可能因为库的默认处理或者跨域预检的影响,导致这个请求头没有正确被发送。你可以:
- 打开浏览器的开发者工具(F12),切换到Network面板
- 触发Flutter里的请求,找到对应的POST请求,查看Request Headers里的
Content-Type是否确实是application/json - 如果发现头不对,尝试将headers的key改为标准的大写格式:
'Content-Type': 'application/json'(HTTP头本身大小写不敏感,但部分服务端处理可能有严格要求)
2. 对齐请求体格式与curl一致
你在Flutter里的请求体中,version字段是字符串类型"1",但curl里是数字类型1。虽然当前你的Cloud Function没有做格式校验,但为了完全对齐curl的请求,建议修改Flutter代码中的请求体:
body: jsonEncode(<String, dynamic>{ "message": "test", "version": 1, // 改为数字类型,和curl保持一致 }),
3. 排查跨域预检请求(OPTIONS)的情况
Flutter Web发起跨域请求时,浏览器会自动发送OPTIONS预检请求,用来确认服务端是否允许跨域。你需要:
- 在Network面板中查看是否有OPTIONS请求,其状态码是否为200
- 如果预检请求失败,说明服务端的CORS配置存在问题。虽然你提到添加了
Access-Control-Allow-Origin: *,但需要确认这个头是在服务端的响应中返回的。你可以修改Cloud Function的代码,显式设置CORS响应头:
import functions_framework @functions_framework.http def my_http_function(request): # 设置CORS响应头 headers = { 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Methods': 'POST, OPTIONS', 'Access-Control-Allow-Headers': 'Content-Type' } # 处理OPTIONS预检请求 if request.method == 'OPTIONS': return ('', 204, headers) print("Request headers:", request.headers) print("Request body:", request.get_data()) return ("OK", 200, headers)
4. 查看Cloud Function的实际请求日志
为了确认服务端接收到的请求到底是什么样的,你可以修改Cloud Function代码,打印请求头和请求体,然后查看Cloud Function的日志:
@functions_framework.http def my_http_function(request): print("Received request headers:", dict(request.headers)) print("Received request body:", request.get_data().decode('utf-8')) return "OK"
部署修改后的函数后,触发Flutter的请求,然后在Google Cloud Console的Cloud Function日志中查看输出,确认服务端收到的Content-Type是否正确,请求体是否为合法的JSON格式。
5. 尝试更换HTTP请求库
有时候http库在Flutter Web环境下会有一些兼容性问题,你可以尝试用dart:io的HttpClient来发送请求,看看是否能解决问题:
import 'dart:io'; import 'dart:convert'; void callCloudFunction() async { final client = HttpClient(); final uri = Uri.parse('https://example.com/function'); final request = await client.postUrl(uri); request.headers.set('Content-Type', 'application/json'); request.write(jsonEncode({"message": "test", "version": 1})); final response = await request.close(); final responseBody = await response.transform(utf8.decoder).join(); print("Status code: ${response.statusCode}"); print("Response body: $responseBody"); client.close(); }
备注:内容来源于stack exchange,提问作者GenError

