Delphi的Datasnap ISAPI模块

时间:2016-08-05 09:35:06

标签: javascript rest delphi cors isapi

我们遇到AngularJS客户端访问的Datasnap REST(Delphi 10.1 Berlin)服务器的问题。我无法激活授权,因为Angular无法在Pragma Header中发送dssession,这似乎是CORS的一个问题,因为浏览器正在改变Header(使用--disable-web启动Chrome) -security flat一切运行良好。)

即使在同一台机器上运行Angular和Datasnap进行测试(本地主机上的Angular:8080和本地主机上的Datasnap:8081),浏览器会将这些调用检测为Cross-Origin调用,当Angular尝试发送dssession时,它不会进行测试。到达Datasnap。注意:我允许使用以下代码进行跨源调用:代码http://delphi.org/2015/04/cors-on-datasnap-rest-server/

将服务器作为StandAlone应用程序运行我可以在WebModuleBeforeDispatch事件中看到TWebRequest获得一个具有值" Pragma"的Access-Control-Request-Headers。而不是预期的Pragma Header,所以看起来浏览器正在发出一个CORS Options请求而Datasnap没有回答它(它引发了一个TDSServiceException,其中"命令已关闭或未分配"消息)。 / p>

我已经为StandAlone应用程序解决了它,通过URL传递了dssession(它不会干扰参数的正常传递,因为我只使用来自AngularJS的POST调用),然后截取WebModuleBeforeDispatch上的Request事件并手动添加带有从调用URL检索到的dssession的Pragma Header。

procedure TWebModule1.WebModuleBeforeDispatch(Sender: TObject; Request: TWebRequest; 
                                              Response: TWebResponse; var Handled: Boolean);
var Token: string;
begin
  Response.SetCustomHeader('Access-Control-Allow-Origin','*');     // Allow CORS calls

  Token := TIdHTTPAppRequest(Request).Query;         // Set session on Pragma from the URL
  if Copy(Token, 1, 10) = 'dssession=' then begin
    TIdHTTPAppRequest(Request).GetRequestInfo.RawHeaders.AddValue('Pragma', Token);
  end;

  if FServerFunctionInvokerAction <> nil then
    FServerFunctionInvokerAction.Enabled := AllowServerFunctionInvoker;
end;

它在StandAlone应用程序上工作正常,但是当我将我的代码重新编译为ISAPI模块以在最终生产环境中部署它时,它并没有在请求中添加dssession Pragma Header,可能是因为它没有&# 39;通过URL传递dssession,但我无法确定原因,因为我无法让我的Delphi调试ISAPI模块。

我遵循本教程:http://edn.embarcadero.com/article/40873我可以正确设置运行我的ISAPI模块,但是当我将w3wp.exe进程附加到我的Delphi调试器时,它不会停止到任何断点(它们看起来是禁用的,就像代码是使用Release Build而不是Debug Build编译的那样,事实上,w3wp.exe进程似乎被冻结,并且在我从Delphi调试器中分离之前不会参加任何调用

所以,我很感激能够调试该模块的任何建议,更重要的是,当浏览器将它们检测为跨源调用时,将dssession传递给ISAPI模块。

非常感谢。

1 个答案:

答案 0 :(得分:2)

我终于找到了一个简洁的解决方案来设置Datasnap来回答CORS请求,因为它应该回答它们。

当您的Datasnap在WebModule.Before dispatch事件上收到COR请求时,您只需回答允许发送自定义标头(Pragma),将Handled设置为True非常重要,因此Datasnap不会尝试管理OPTION请求作为调用方法的正常请求。

procedure TWebModule1.WebModuleBeforeDispatch(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
begin
  Response.SetCustomHeader('Access-Control-Allow-Origin','*');        

  if Trim(Request.GetFieldByName('Access-Control-Request-Headers')) <> '' then 
  begin 
    Response.SetCustomHeader('Access-Control-Allow-Headers', Request.GetFieldByName('Access-Control-Request-Headers'));        
    Handled := True;
  end;

  if FServerFunctionInvokerAction <> nil then
    FServerFunctionInvokerAction.Enabled := AllowServerFunctionInvoker;
end;