2016-08-05 25 views
1

AngularJSクライアントがアクセスするDatasnap REST(Delphi 10.1 Berlin)サーバに問題があります。 Angularがプラグマヘッダー内でdssessionを送信できないため、認可を有効にできません。CORSに問題があるように見えます。ブラウザがそのヘッダーを変更しているためです(--disable-web-security flatですべてを起動うまくいく)。DelphiのDatasnap ISAPIモジュールのCORS問題

同じマシンでAngularとDatasnapを実行しても(localhost:8080の角度とlocalhost:8081の角度)、ブラウザーは呼び出しをCross-Origin呼び出しとして検出し、Angularがdssessionを送信しようとすると、 Datasnapに到着します。注:私は以下を使用してクロスオリジン呼び出しを許可します:コードhttp://delphi.org/2015/04/cors-on-datasnap-rest-server/

サーバをスタンドアロンアプリケーションとして実行WebModuleBeforeDispatchイベントで、TWebRequestが値 "Pragma"を持つアクセス制御要求ヘッダーを取得することがわかります。期待されたプラグマヘッダーの代わりに、ブラウザがCORSオプション要求を出しているように見え、Datasnapはそれに応答しません( "コマンドが閉じられているか、割り当てられていません"というメッセージでTDSServiceExceptionが発生します)。

私はStandAloneアプリケーションのためにURLを使ってdssessionを渡しました(私はAngularJSのPOSTコールしか使用しないため、パラメータの通常の通過を妨げません)。そして、WebModuleBeforeDispatchイベントのリクエストをインターセプトします。呼び出し元のURLから取得したdssessionを含むプラグマヘッダーを手動で追加します。

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プラグマヘッダーを追加しません。私はDelphiにISAPIモジュールをデバッグすることができないので、その理由を確認することはできません。

私はこのチュートリアルに従います:http://edn.embarcadero.com/article/40873とISAPIモジュールを正しく実行するように設定できますが、w3wp.exeプロセスをDelphiデバッガに接続すると、ブレークポイントは停止しません。デバッグビルドの代わりにリリースビルドでコンパイルされたコードのように)、実際には、w3wp.exeプロセスはフリーズしているようだが、Delphiデバッガからデタッチするまで呼び出されない。

このモジュールをデバッグでき、さらに重要なことは、ブラウザがクロスソースコールとしてそれらを検出したときにISAPIモジュールにdssessionを渡すことができればと思います。

ありがとうございました。

+0

サーバのCORSサポートにはプリフライト処理が含まれていますか? –

+0

私はそれに関するドキュメントを見つけることができませんが、実際には、Datasnapはプリフライト処理をサポートしていないようです:-(それが、私がそれを避けようとした理由、カスタマイズされたヘッダープラグマを使用して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

Delphi XE2 TISAPIRequest.GetFieldByName(...)がHTTP_プレフィックスを使用するため、私の環境(Delphi XE2、単純なWebBroker ISAPIモジュール、Apache 2.4とmod_isapi)でアクセス制御要求ヘッダーをAccess_Control_Request_Headersに変更しなければなりませんでしたHEADER_ではなくHEADER_。HTTP_およびHEADER_については、https://msdn.microsoft.com/en-us/library/ms524602%28v=vs.90%29.aspx?f=255&MSPPError=-2147217396を参照してください。 – Chris

関連する問題