You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Shopify自定义HTML表单对接Flutter Firebase应用失败排查咨询

问题背景

我是新手,在Shopify自定义页面部署了如下HTML表单:

<form method="POST" action="https://fb-test.web.app:8080" id="myForm">
<label for="name">Name:</label> <input required="" type="text"> <input value="Submit" type="submit">
</form>

我开发了一个Flutter应用,使用shelf包监听请求,最终将数据写入Firestore数据库,该应用部署在谷歌云,运行状态正常,代码如下:

void main() async {

  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp(
    options: DefaultFirebaseOptions.currentPlatform,
  );

  final handler = Pipeline().addMiddleware(logRequests()).addHandler(_echoRequest);

  final server = await serve(handler, 'localhost', 8080);
  print('Server listening on port ${server.port}');

//  runApp(const MyApp());
}


Future<Response> _echoRequest(Request request) async {
  if (request.method == 'POST') {
    final contentType = request.headers['content-type'];
    if (contentType != null && contentType.contains('application/x-www-form-urlencoded')) {
      final form = await request.readAsString();
      final parameters = Uri.splitQueryString(form);
      final name = parameters['name'] ?? 'Unknown';

      // Process the form data here
      print('Name: $name');
      writeFulfillmentRequest(name);


      return Response.ok('Form submitted successfully!');
    }
  }
  return Response.notFound('Not Found');
}

Future<void> writeFulfillmentRequest(String name) async {
  db.collection('quote-request-info').doc;
  if (name != '') {
    await quoteRequestCollection.doc(quoteRequestCollection.id).set({'name': name});
  }
}

在Shopify页面输入信息并点击提交后,页面长时间加载后返回"请求超时"错误,数据未写入Firestore。现咨询:

  1. 问题出在哪里?
  2. 如何捕获并显示表单提交的响应?

补充调试信息

根据建议移除了端口号,并通过Firefox开发者工具调试,得到如下日志:

TSS: excluded result:  false content-scripts.js:1:61930
content-tss TSS: hosted page injected fb-test-app.web.app:3:51
content-tss MBTSS: Nonce:  yufinut1v0psa9p356d4v9or6ocy6k2pq944vnosu9kd fb-test-.web.app:3:99
Loading from existing service worker. flutter_bootstrap.js:3:659
Service worker already active. flutter_bootstrap.js:3:907
Injecting <script> tag. Using callback. flutter_bootstrap.js:1:1846
Source map error: Error: request failed with status 404
Stack in the worker:networkRequest@resource://devtools/client/shared/source-map-loader/utils/network-request.js:43:9

Resource URL: https://fb-test-app.web.app/flutter_bootstrap.js
Source Map URL: flutter.js.map

发现存在404错误,请问是否需要在请求中重新添加端口号?


问题分析与解决

1. 核心问题排查

(1)服务器监听地址错误

后端代码里serve(handler, 'localhost', 8080)是监听本地localhost,部署到谷歌云后外部请求无法访问。必须改成监听所有IP:

final server = await serve(handler, '0.0.0.0', 8080);

(2)云服务端口配置缺失

  • 谷歌云控制台需在防火墙规则中开放8080端口,允许外部HTTP/HTTPS流量进入。
  • 若用App Engine,默认不暴露自定义端口,需配置端口映射,或直接使用80/443默认端口(修改代码端口为80,同步云服务配置)。
  • 之前带端口超时是因为外部请求无法触达localhost的服务器;去掉端口后404是因为云服务未将请求转发到8080端口,或服务器监听地址错误。

(3)表单输入字段缺失name属性

HTML输入框<input required="" type="text">没有name="name"属性,导致提交时不携带name参数,后端拿不到有效数据。需修改:

<input required="" type="text" name="name">

(4)Firestore写入代码错误

writeFulfillmentRequest函数有两处问题:

  • db.collection('quote-request-info').doc;是无效代码,无实际作用。
  • quoteRequestCollection.doc(quoteRequestCollection.id)写法错误,正确生成文档ID的方式如下:
Future<void> writeFulfillmentRequest(String name) async {
  if (name.isNotEmpty) {
    // 自动生成文档ID写入
    await db.collection('quote-request-info').doc().set({'name': name});
  }
}

2. 捕获并显示表单提交响应

默认表单提交会跳转页面,无法捕获响应,需用JavaScript异步提交:

<form method="POST" action="https://fb-test.web.app" id="myForm">
  <label for="name">Name:</label> 
  <input required="" type="text" name="name"> 
  <input value="Submit" type="submit">
</form>
<div id="response-message"></div>

<script>
document.getElementById('myForm').addEventListener('submit', async (e) => {
  e.preventDefault(); // 阻止默认页面跳转
  const formData = new FormData(e.target);
  const responseDiv = document.getElementById('response-message');
  
  try {
    const response = await fetch(e.target.action, {
      method: 'POST',
      body: new URLSearchParams(formData),
      headers: {
        'Content-Type': 'application/x-www-form-urlencoded'
      }
    });
    
    const result = await response.text();
    responseDiv.textContent = result;
    responseDiv.style.color = 'green';
  } catch (error) {
    responseDiv.textContent = '提交失败:' + error.message;
    responseDiv.style.color = 'red';
  }
});
</script>

关于404错误的疑问

不需要重新添加端口号,重点解决以下两点:

  1. 确保后端监听0.0.0.0:8080,并且谷歌云防火墙开放8080端口。
  2. 若使用反向代理或App Engine,需配置端口转发,将外部80/443端口的请求转发到后端8080端口。
    日志中的flutter_bootstrap.js 404是Flutter Web资源问题,与表单提交的接口无关,不影响后端API的请求处理。

内容的提问来源于stack exchange,提问作者APEGamer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 11:22:04