我们遇到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模块。
非常感谢。
答案 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;