我正在制作一个小型服务器类型的应用程序。
在Web浏览器中,我希望用户输入服务器地址并登录,然后我的服务器必须返回服务器上存在的文件的路径。该文件必须在用户的本地计算机上运行(这些是小型Excel文件,因此它可能会很快运行)。
有可能吗?我是否必须先下载文件然后运行它?
该文件应在登录后自动运行,因此我的服务器必须将文件发送到客户端计算机并在客户端计算机上运行。
你能告诉我一个小例子吗?
P.S。我使用Indy组件,但如果有人有更好的想法,我可以接受建议。
答案 0 :(得分:1)
您要求的是技术上在HTTP中可行,因为对任何HTTP请求的响应可以是实际的Excel文件。例如:
使用HTTP身份验证:
procedure TMyForm.IdHTTPServer1CommandGet(AContext: TIdContext; ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
begin
if ARequestInfo.Document = '/myfile.xlsx' then
begin
if not ARequestInfo.AuthExists then
begin
AResponseInfo.AuthRealm := 'myserver';
Exit;
end;
if not UserIsAuthenticated(ARequestInfo.AuthUsername, ARequestInfo.AuthPassword) then
begin
AResponseInfo.ResponseNo := 403;
Exit;
end;
case ARequestInfo.CommandType of
hcGET:
begin
AResponseInfo.SmartServeFile(AContext, ARequestInfo, '<path>\myfile.xlsx');
end;
hcHEAD:
begin
AResponseInfo.ContentType := IdHTTPServer1.MIMETable.GetFileMIMEType('myfile.xlsx');
AResponseInfo.ContentLength := FileSizeByName('<path>\myfile.xlsx');
AResponseInfo.ContentDisposition := 'attachment; filename="myfile.xlsx";';
end;
else
AResponseInfo.ResponseNo := 405;
end;
end else
begin
AResponseInfo.ResponseNo := 404;
end;
end;
使用HTML webform身份验证:
的index.html
<html>
<head>
<title>login</title>
</head>
<body>
<form action="/login" method="POST">
Username: <input type="text" name="user"><br>
Password: <input type="password" name="pswd"><br>
<input type="submit" value="Submit"> <input type="reset" value="Clear">
</form>
</body>
</html>
procedure TMyForm.IdHTTPServer1CommandGet(AContext: TIdContext; ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
begin
if ARequestInfo.Document = '/' then
begin
case ARequestInfo.CommandType of
hcGET, hcHEAD:
begin
AResponseInfo.ContentType := 'text/html';
if ARequestInfo.CommandType = hcGET then
AResponseInfo.ContentStream := TIdReadFileExclusiveStream.Create('<path>\index.html')
else
AResponseInfo.ContentLength := FileSizeByName('<path>\index.html');
end;
else
AResponseInfo.ResponseNo := 405;
end;
end
else if ARequestInfo.Document = '/login' then
begin
if ARequestInfo.CommandType <> hcPOST then
begin
AResponseInfo.ResponseNo := 405;
Exit;
end;
if not UserIsAuthenticated(ARequestInfo.Params.Values['user'], ARequestInfo.Params.Values['pswd']) then
begin
AResponseInfo.ResponseNo := 403;
Exit;
end;
AResponseInfo.ServeFile(AContext, '<path>\myfile.xlsx');
end else
begin
AResponseInfo.ResponseNo := 404;
end;
end;
可替换地:
// make sure to set TIdHTTPServer.SessionState=True...
procedure TMyForm.IdHTTPServer1CommandGet(AContext: TIdContext; ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
begin
if ARequestInfo.Document = '/' then
begin
case ARequestInfo.CommandType of
hcGET, hcHEAD:
begin
AResponseInfo.ContentType := 'text/html';
if ARequestInfo.CommandType = hcGET then
AResponseInfo.ContentStream := TIdReadFileExclusiveStream.Create('<path>\index.html')
else
AResponseInfo.ContentLength := FileSizeByName('<path>\index.html');
end;
else
AResponseInfo.ResponseNo := 405;
end;
end
else if ARequestInfo.Document = '/login' then
begin
if ARequestInfo.CommandType <> hcPOST then
begin
AResponseInfo.ResponseNo := 405;
Exit;
end;
if ARequestInfo.Session = nil then
begin
IdHTTPServer1.CreateSession(AContext, AResponseInfo, ARequestInfo);
end;
if not UserIsAuthenticated(ARequestInfo.Params.Values['user'], ARequestInfo.Params.Values['pswd']) then
begin
AResponseInfo.Session.Content.Values['AuthOK'] := 'no';
AResponseInfo.ResponseNo := 403;
Exit;
end;
AResponseInfo.Session.Content.Values['AuthOK'] := 'yes';
//AResponseInfo.Redirect('/myfile.xlsx');
AResponseInfo.ResponseNo := 303;
AResponseInfo.Location := '/myfile.xlsx';
end
else if ARequestInfo.Document = '/myfile.xlsx' then
begin
if ARequestInfo.AuthExists then
begin
if ARequestInfo.Session = nil then
begin
IdHTTPServer1.CreateSession(AContext, AResponseInfo, ARequestInfo);
end;
ARequestInfo.Session.Content.Values['AuthOK'] := iif(UserIsAuthenticated(ARequestInfo.AuthUsername, ARequestInfo.AuthPassword), 'yes', 'no');
end;
if (ARequestInfo.Session = nil) or (ARequestInfo.Session.Content.IndexOf('AuthOK') = -1) then
begin
//AResponseInfo.Redirect('/');
AResponseInfo.ResponseNo := 303;
AResponseInfo.Location := '/';
Exit;
end;
if ARequestInfo.Session.Content.Values['AuthOK'] <> 'yes' then
begin
AResponseInfo.ResponseNo := 403;
Exit;
end;
case ARequestInfo.CommandType of
hcGET:
begin
AResponseInfo.SmartServeFile(AContext, ARequestInfo, '<path>\myfile.xlsx');
end;
hcHEAD:
begin
AResponseInfo.ContentType := IdHTTPServer1.MIMETable.GetFileMIMEType('myfile.xlsx');
AResponseInfo.ContentLength := FileSizeByName('<path>\myfile.xlsx');
AResponseInfo.ContentDisposition := 'attachment; filename="myfile.xlsx";';
end;
else
AResponseInfo.ResponseNo := 405;
end;
end else
begin
AResponseInfo.ResponseNo := 404;
end;
end;
然而,无论哪种方式,都必须事先配置用户的Web浏览器以自动打开Excel中的.xlsx
文件(或他们想要的任何查看器/编辑器),或者至少提示用户是否打开文件。服务器无法强制自动打开文件,这会破坏用户的安全性。