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

Dart编写的代理服务器返回HTML而非网页问题求助

问题解决:Dart代理服务器转发HTML后浏览器显示源码

你的问题核心是没有转发目标服务器返回的响应头,浏览器因为缺少Content-Type这类关键头信息,不知道收到的内容是HTML,所以直接显示源码了。下面是具体的修复方案:

关键修复点

  • 转发目标响应的状态码
  • 完整转发所有响应头(尤其是Content-Type)
  • 用字节流写入响应内容,避免编码或二进制内容(如图片)出错

修复后的代码

import 'package:http/http.dart' as http;
import 'dart:io';

void launchProxy() async {
  var server = await HttpServer.bind('localhost', 8080);
  await server.forEach((HttpRequest request) async {
    // 处理请求头:用逗号拼接多值header,比替换[]更规范
    final headers = <String, String>{};
    request.headers.forEach((name, values) {
      headers.putIfAbsent(name, () => values.join(','));
    });

    if (request.method == 'GET') {
      final response = await http.get(request.uri, headers: headers);
      // 1. 转发状态码
      request.response.statusCode = response.statusCode;
      // 2. 转发所有响应头
      response.headers.forEach((name, values) {
        request.response.headers.set(name, values.join(','));
      });
      // 3. 用字节流写入内容,兼容文本和二进制资源
      request.response.add(response.bodyBytes);
      await request.response.close();
    } 
    else if (request.method == 'POST') {
      final bodyBytes = await request.first;
      final response = await http.post(request.uri, headers: headers, body: bodyBytes);
      // 同样的转发逻辑
      request.response.statusCode = response.statusCode;
      response.headers.forEach((name, values) {
        request.response.headers.set(name, values.join(','));
      });
      request.response.add(response.bodyBytes);
      await request.response.close();
    }
    // 其他方法可参照上述逻辑添加
  });
}

修复说明

  1. 响应头转发:目标服务器返回的Content-Type: text/html; charset=utf-8会告诉浏览器“这是HTML内容,要渲染”,之前的代码没传这个头,浏览器只能把内容当纯文本显示。
  2. 状态码转发:比如404、500这类状态码也需要正确传递,保证浏览器能识别错误状态。
  3. 字节流写入:response.body会把内容转成字符串,对于图片、视频这类二进制资源会出错,用bodyBytes直接传递原始字节更可靠。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 03:17:47