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

Indy Http Server 交付JavaScript出现语法错误的技术问询

Indy HTTP Server 发送JavaScript文件时的字符编码问题

我尝试用Indy部署Swagger UI(通过提供JavaScript文件渲染API文档),实现代码如下:

procedure TfmMain.SendJavaScriptFileResponse(AResponseInfo: TIdHTTPResponseInfo; AFileName: String);
begin
  AResponseInfo.ContentType := 'application/javascript';
  AResponseInfo.CharSet := 'utf-8';
  var LFileContents := TStringList.Create;
  try
    LFileContents.LoadFromFile(AFileName);
    AResponseInfo.ContentText := LFileContents.Text;
  finally
    LFileContents.Free;
  end;
end;

浏览器运行该JavaScript时抛出语法错误:

Uncaught SyntaxError: illegal character U+20AC

从Indy IdHttpServer收到的响应头如下:

HTTP/1.1 200 OK
Connection: close
Content-Encoding: utf-8
Content-Type: application/javascript; charset=utf-8
Content-Length: 1063786
Date: Sun, 05 Feb 2023 20:45:56 GMT

但相同的JavaScript文件放到托管网站提供时,浏览器运行完全正常。想问用Indy HTTP Server发送JS文件时,是否需要调整特定设置或字符集?


问题根源

你的代码用TStringList.LoadFromFile读取JS文件时,默认会使用系统默认ANSI编码解析文件,而非UTF-8。如果JS文件本身是UTF-8编码(尤其是包含€(U+20AC)这类非ANSI字符时),ANSI编码读取会导致字符乱码,最终传给浏览器的内容就会包含非法字符。

另外响应头里多余的Content-Encoding: utf-8是错误设置——这个头用于标识内容的压缩编码(比如gzip),不是字符编码,会让浏览器误解内容处理逻辑。

修复方案

  1. 正确读取UTF-8文件
    改用TStringList的重载方法,明确指定UTF-8编码读取文件:

    procedure TfmMain.SendJavaScriptFileResponse(AResponseInfo: TIdHTTPResponseInfo; AFileName: String);
    begin
      AResponseInfo.ContentType := 'application/javascript';
      AResponseInfo.CharSet := 'utf-8';
      // 移除错误的Content-Encoding设置
      AResponseInfo.ContentEncoding := '';
      var LFileContents := TStringList.Create;
      try
        // 指定UTF-8编码读取文件
        LFileContents.LoadFromFile(AFileName, TEncoding.UTF8);
        AResponseInfo.ContentText := LFileContents.Text;
      finally
        LFileContents.Free;
      end;
    end;
    
  2. 更高效的文件发送方式
    如果JS文件体积较大,直接用ContentStream发送原始字节流,避免编码转换带来的问题,同时提升性能:

    procedure TfmMain.SendJavaScriptFileResponse(AResponseInfo: TIdHTTPResponseInfo; AFileName: String);
    begin
      AResponseInfo.ContentType := 'application/javascript';
      AResponseInfo.CharSet := 'utf-8';
      AResponseInfo.ContentEncoding := '';
      // 直接发送文件流,跳过字符串转换步骤
      AResponseInfo.ContentStream := TFileStream.Create(AFileName, fmOpenRead or fmShareDenyWrite);
      // Indy会自动计算并设置Content-Length,也可手动指定
      // AResponseInfo.ContentLength := AResponseInfo.ContentStream.Size;
    end;
    

    注意:使用ContentStream时,Indy会在请求结束后自动释放流,无需手动调用Free。

  3. 验证文件编码
    确认你的JS文件确实是UTF-8编码(可通过记事本打开后选择“另存为”查看编码选项)。无论文件带不带BOM,TEncoding.UTF8都能正确读取。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 15:31:49