2016-08-05 3 views
1

AngularJS 클라이언트가 액세스하는 Datasnap REST (Delphi 10.1 Berlin) 서버에 문제가 있습니다. Angular가 Pragma Header 내 dssession을 보낼 수 없기 때문에 권한 부여를 활성화 할 수 없습니다. CORS에 문제가있는 것 같습니다. 브라우저가 Header를 변경하기 때문입니다 (--disable-web-security flat으로 Chrome을 시작합니다. 잘 실행됩니다.)Delphi의 Datasnap ISAPI 모듈에서 CORS 문제

동일한 기계에서 Angular와 Datasnap을 실행 (localhost : 8080 및 Datastap : localhost : 8081의 각도)하여 실행하는 경우 브라우저는 Cross-Origin 호출로 호출을 감지하고 Angular가 dssession을 보내려고 시도 할 때 ' Datasnap에 도착합니다. 참고 : 다음을 사용하여 교차 원점 호출을 허용합니다. 코드 http://delphi.org/2015/04/cors-on-datasnap-rest-server/

서버를 독립 실행 형 응용 프로그램으로 실행 WebModuleBeforeDispatch 이벤트에서 TWebRequest가 "Pragma"값을 가진 액세스 제어 요청 헤더를 얻는 것을 볼 수 있습니다. 예상 된 Pragma Header 대신 브라우저가 CORS Options 요청을 발행하고 Datasnap이 응답하지 않는 것처럼 보입니다 ("명령이 닫혔거나 할당되지 않았습니다"라는 메시지와 함께 TDSServiceException가 발생합니다).

나는 AnglesJS의 POST 호출 만 사용하기 때문에 매개 변수의 일반 전달을 방해하지 않고 URL을 통해 dssession을 전달한 다음, WebModuleBeforeDispatch 이벤트에서 요청을 가로 채고 StandAlone 응용 프로그램에 대해 해결했습니다. 호출 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; 

그것은 그 독립형 응용 프로그램에서 잘 작동하지만 최종 프로덕션 환경에 배포하는 ISAPI 모듈로 내 코드를 다시 컴파일 할 때, 그것의 요청에 dssession에서 Pragma 헤더를 추가하지 않습니다 아마도 때문에 URL을 통해 dssession을 전달하지는 않지만, 델파이에서 ISAPI 모듈을 디버그 할 수 없기 때문에 그 이유를 알 수 없습니다.

http://edn.embarcadero.com/article/40873에 따라 ISAPI 모듈을 올바르게 실행하도록 설정할 수 있지만 w3wp.exe 프로세스를 Delphi 디버거에 연결하면 중단 점까지 멈추지 않습니다. 코드가 디버그 빌드 대신 릴리즈 빌드로 컴파일 된 것처럼) 실제로 w3wp.exe 프로세스는 멈춘 것처럼 보이고 델파이 디버거에서 분리 될 때까지 호출에 참여하지 않습니다.

그래서이 모듈을 디버깅하고 더 중요한 것은 ISAPI 모듈에 브라우저가 교차 호출을 감지하면 dssession을 전달할 수있는 제안을 해주시면 감사하겠습니다.

대단히 감사합니다.

+0

서버 CORS 지원에는 프리 플라이트 처리가 포함되어 있습니까? 당신이 제공 한 링크에 대한 마지막 두 개의 코멘트는 그렇지 않습니다. –

+0

Datasnap은 프리 플라이트 처리를 지원하지 않습니다. (그런 이유로 나는 그것을 피하려고했으나 사용자 정의 된 header Pragma를 사용하여 URL을 통해 dssession을 보냅니다.) –

+0

Angular에 대해 충분히 알지 못하지만 실제로 모든 클라이언트 측 (javascript) 파일 인 경우 동일한 IIS 인스턴스에서 둘 다 호스팅하지 마십시오. 선택적으로 가상 디렉터리를 사용하십시오. 도메인 간 점검은 실행되지 않습니다. –

답변

2

마침내 Datasnap이 CORS 요청에 응답하도록 정교한 솔루션을 찾았습니다.

Datasnap이 WebModule.Before 발송 이벤트에서 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; 
+1

델파이 XE2에서 TISAPIRequest.GetFieldByName (...)이 HTTP_ 접두어를 사용하기 때문에 AccessControl_Request_Headers로 액세스 제어 요청 헤더를 변경해야했습니다 (델파이 XE2, 간단한 WebBroker ISAPI 모듈, 아파치 2.4, mod_isapi 사용) HEADER_ 대신 HTTP_ 및 HEADER_를 참조하십시오. https://msdn.microsoft.com/en-us/library/ms524602%28v=vs.90%29.aspx?f=255&MSPPError=-2147217396을 참조하십시오. – Chris