Проблема с CORS в модуле Delphi Datasnap ISAPI
У нас проблема с сервером REST (Delphi 10.1 Berlin) Datasnap, к которому обращаются клиенты AngularJS. Я не могу активировать авторизацию, потому что Angular не может отправить dssession в Pragma Header, похоже, это проблема с CORS, потому что браузер меняет этот заголовок (запуск Chrome с помощью --disable-web-security устраняет все работает нормально).
Даже запуская Angular и Datasnap на одной машине для тестирования (Angular на локальном хосте:8080 и Datasnap на локальном хосте:8081), браузер обнаруживает вызовы как вызовы из разных источников, и когда Angular пытается отправить dssession, он не приходит в Datasnap, Примечание. Я разрешаю звонки из разных стран, используя следующий код: code http://delphi.org/2015/04/cors-on-datasnap-rest-server/
Запуская Сервер как автономное приложение, я вижу в событии WebModuleBeforeDispatch, что TWebRequest получает Access-Control-Request-Headers со значением "Pragma" вместо ожидаемого Pragma Header, поэтому похоже, что браузер выдает параметры CORS запрос и Datasnap не отвечает на него (он вызывает TDSServiceException с сообщением "команда закрыта или не назначена").
Я решил это для приложения StandAlone, пропустив dssession через URL (он не мешает нормальной передаче параметров, потому что я использую только вызовы POST из AngularJS), а затем перехватил запрос на событие WebModuleBeforeDispatch и вручную добавил Заголовок Pragma с dssession, полученным из вызывающего URL.
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 для развертывания его в конечной производственной среде, он не добавляет заголовок Pragma dssession в запросы, возможно, потому, что он не передал dssession. через URL, но я не могу быть уверен в причине, потому что я не могу заставить свой Delphi отлаживать этот модуль ISAPI.
Я следую этому уроку: http://edn.embarcadero.com/article/40873 и могу правильно настроить запуск модуля ISAPI, но когда я присоединяю процесс w3wp.exe к моему отладчику Delphi, он не останавливается ни перед каким разрывом -point (они выглядят отключенными, как будто код был скомпилирован с помощью Release Build вместо Debug Build), фактически процесс w3wp.exe кажется замороженным и не посещает никаких вызовов, пока я не отсоединю его от Delphi отладчик.
Итак, я был бы признателен за любое предложение, чтобы иметь возможность отладки этого модуля, и что более важно, передать передачу в модуль ISAPI, когда ваш браузер обнаруживает их как вызовы Cross-Origin.
Большое спасибо.
1 ответ
Наконец-то я нашел изящное решение, позволяющее Datasnap отвечать на запросы CORS так, как он должен на них отвечать.
Когда ваш Datasnap получает запрос COR на событие WebModule.Before, вам просто нужно ответить, чтобы разрешить отправку настроенного заголовка (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;