Indy TIdHTTPServer OnCommandGet javascript in html not execu

Indy TIdHTTPServer OnCommandGet javascript in html not executing

本文关键字:html not execu in javascript TIdHTTPServer OnCommandGet Indy      更新时间:2023-09-26

我有一个TIdHTTPServer,它将html文件中的javascript代码发送到浏览器,并在<head>标签中带有标签<script language="javascript">。我无权访问 html 文件,因此无法更改其内容。我使用HTTPServerCommandGet将该文件的内容发送到浏览器,如下所示:

procedure TMainForm.HTTPServerCommandGet(AContext: TIdContext;
  ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
var
  responseMemoryStream : TMemoryStream;
begin
  responseMemoryStream := TMemoryStream.Create;
  try
    AResponseInfo.ContentType := 'text/html';
    AResponseInfo.ContentEncoding := 'UTF-8';
    AResponseInfo.CharSet := 'UTF-8';
    responseMemoryStream.LoadFromFile(ExtractFilePath(Application.ExeName) + 'index.html');
    AResponseInfo.ContentStream := TMemoryStream.Create;
    TMemoryStream(AResponseInfo.ContentStream).LoadFromStream(responseMemoryStream);
  finally
    responseMemoryStream.Free;
  end;
end;

当我从互联网浏览器发出GET命令时,它有时会加载javascript,但有时不会 - 当我使用Firefox时没有问题,但是当我使用ChromeIE时,javascript永远不会执行。有没有办法以某种方式使用 AResponseInfo 变量强制执行 javascript 代码,或者我无能为力来解决这个问题?

这是index.html的一部分:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta name="keywords" content="" />
    <meta name="description" content="" />
    <meta  charset=utf8 />
    <title>My title</title>
    <script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?sensor=false"></script>
    <script language="javascript">
        var map;
        var flag_for_map_massage = 0;
        var map_marker = 0;
        function initmap()
        {
            var html;
            var map_divtxt = "<div id='"map_canvas'" style='"width:200px;height:150px;'" ></div>";
            document.getElementById("google_map").innerHTML = map_divtxt;
            var latlng = new google.maps.LatLng(100.12345, 200.12345);
            var options = {
                zoom: 17,
                center: latlng,
                mapTypeId: google.maps.MapTypeId.ROADMAP
            };
            var map1 = new google.maps.Map(document.getElementById("map_canvas"), options);
            var html = "<table>" +
                    "<tr><td>GMBH Address</td> </tr>";
            infowindow = new google.maps.InfoWindow({
                content: html
            });
            var marker1 = new google.maps.Marker({
                position: new google.maps.LatLng(100.12345, 200.12345),
                map: map1
            });
            //     infowindow.open(map1, marker1);
            google.maps.event.addListener(marker1, "click", function() {
                infowindow.open(map1, marker1);
            });
        }
    </script>
</head>
<body onload="initmap();">  
  <div class="entry">
    <div id="google_map">
    </div>
  </div> 
</body>
</html>

您的服务器所能做的就是将 HTML 传送到浏览器,仅此而已。 浏览器负责处理 HTML、检索外部资源、执行脚本等。 如果浏览器无法正常运行,则可能是HTML/脚本一开始就有错误。 这与您的服务器无关(除非您正在损坏要发送的数据)。

话虽如此,您不需要在OnCommandGet代码中使用两个流,这是矫枉过正。 一个流就足够了。 此外,utf-8不是有效的ContentEncoding值,因此您需要将其删除。

试试这个:

procedure TMainForm.HTTPServerCommandGet(AContext: TIdContext;
  ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
begin
  AResponseInfo.ContentType := 'text/html';
  AResponseInfo.CharSet := 'utf-8';
  AResponseInfo.ContentStream := TMemoryStream.Create;
  TMemoryStream(AResponseInfo.ContentStream).LoadFromFile(ExtractFilePath(Application.ExeName) + 'index.html');
end;

或者:

procedure TMainForm.HTTPServerCommandGet(AContext: TIdContext;
  ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
begin
  AResponseInfo.ContentType := 'text/html';
  AResponseInfo.CharSet := 'utf-8';
  AResponseInfo.ContentStream := TIdReadFileExclusiveStream.Create(ExtractFilePath(Application.ExeName) + 'index.html');
end;

而且,当然,请确保您关注ARequestInfo.Document属性,并且仅在浏览器实际请求index.html而不是服务器上的其他文件时才提供index.html

Indy10的IdCustomHTTPServer.pas有一个bug。

设置 AResponseInfo.Charset 值不起作用。因为以下行(Pas 文件中的第 2141 行)覆盖了字符集变量。

  if ContentType = '' then begin
    if (ContentText <> '') or (Assigned(ContentStream)) then begin
      ContentType := 'text/html; charset=ISO-8859-1'; {Do not Localize} 

为了更正,请在下面添加两个文件(从"C:''Program Files (x86)''Embarcadero''Studio''16.0''source''Indy10''Core"复制到项目目录,然后添加到项目中):

IdCustomHTTP.pas

IdCompilerDefines.inc

将第 2141 行修改为

ContentType := 'text/html; charset='+Charset;

;-)