• ベストアンサー

処理終了後、他のプログラムへPOST方式でsubmitする方法

処理終了後、他のプログラムへPOST方式でsubmitする方法はないでしょうか。 GET方式を使えば出来ますが、POST方式で値を渡したいのですが、可能でしょうか。 (JavaScriptは使わず。)

質問者が選んだベストアンサー

  • ベストアンサー
回答No.3

なるほど、片方がPHPでしたか。それではやむを得ないかもしれませんね。 一応お書きになったような内容で、当方の環境だと成功するのですが…。 write.cgiを呼び出すopenが失敗しているのかもしれません。失敗するとdieで そのエラーメッセージを出力してますが、これはサーバのerror_logに出力 されるので、ブラウザからでは確認できませんね。失礼しました。 ではstart.cgiを以下のように修正してみてはどうでしょう。 #!/usr/local/bin/perl $param = 'a=123&b=xyz'; $ENV{CONTENT_LENGTH} = length($param); $ENV{REQUEST_METHOD} = 'POST'; print "Content-type: text/html\n\n"; open(OTHER_CGI, "|./write.cgi") or print "error: $!"; print OTHER_CGI $param; close(OTHER_CGI); print "success!"; 要するに成功したらsuccess、失敗したらerror:でエラーメッセージを 出すようにしたわけです。Content-typeヘッダの後じゃないとちゃんと 出力されないのでその行も上に移動させてください。 ひょっとすると、CGIが実行されるときのカレントディレクトリが 違うのかもしれませんね。./write.cgiをフルパス、すなわち 例えば/my/home/directory/にあるのでしたら 「/my/home/directory/write.cgi」として指定してみてはどうでしょう? (URLではこの場合ダメです)

defd
質問者

補足

出来ました!! どうやらwindows上で行っていたのが原因のようで、 linux で行ったところ、success表示とともに、ファイルが生成されました。 そして、変数の受け渡しも出来ました!! 詳しい説明、どうもありがとうございました。

その他の回答 (2)

回答No.2

私の推測は当たっていたようですね。(せめて当たっていたかどうか をお教えくださると嬉しいのですが) $ENV{CONTENT_LENGTH} = length($param); $ENV{REQUEST_METHOD} = 'POST'; も必ず実行してください。また、abc.cgiはただの例ですから、 適宜二つ目のCGIの名前を指すよう変更してくださいね。 > CGIのなかから、他のCGIを実行させる、というのはやったことがないもので、、、 やったことがある人はかなり少ないと思います。というのは普通 その必要はないからです。 No.1にも書きましたが、私なら > まあ普通ここまでする前に、どちらのプログラムも自分で編集できるなら > 共通部分をライブラリ(モジュール)として別ファイルにくくり出して、 なんとかします。例えば、ファイルを生成する部分を共有するのだったら 1. ファイルを生成するサブルーチン(仮にfileputとします)だけを まとめて util.pl(別に名前はなんでもいいんですが)とする。 2.1つ目のCGI の最初のほうに require "util.pl"; と書いてutil.plを読みこみ、ファイル生成のときには &fileputを 呼び出して生成させる。 3. 2つ目のCGIも同じように require "util.pl"; と書いて、やはりfileputを呼び出す。 それとも2つ目のCGIはもらいものかなにかでご自分で直すのが たいへんなものなのでしょうか?具体的に言うとどんなことを おやりになりたいんですか?

defd
質問者

補足

>私の推測は当たっていたようですね。(せめて当たっていたかどうか >をお教えくださると嬉しいのですが) 大当たりです。 >$ENV{CONTENT_LENGTH} = length($param); >$ENV{REQUEST_METHOD} = 'POST'; >も必ず実行してください。また、abc.cgiはただの例ですから、 これも、やっているのですが、うまくいきません。 > 共通部分をライブラリ(モジュール)として別ファイルにくくり出して、 実は、二つのファイルは、perl で書いたものと、 PHP で書いたものなので、 共通部分をライブラリ、というわけにもいかなくて、、 とりあえず、CGIから他のCGIが実行できるかのテスト用にと、 #-----------# # start.cgi  #  そのまま #-----------# #!/usr/local/bin/perl $param = 'a=123&b=xyz'; $ENV{CONTENT_LENGTH} = length($param); $ENV{REQUEST_METHOD} = 'POST'; open(OTHER_CGI, "|./write.cgi") or die "$!"; print OTHER_CGI $param; close(OTHER_CGI); print "Content-type: text/html\n\n"; #-----------# # write.cgi  #  送られてる$paramはとりあえず無視 #-----------# #!/usr/local/bin/perl open(DATA, ">./test.dat"); print DATA "aiueo"; close(DATA); で、start.cgi にアクセスしてみるのですが、write.cgi は全然動いてません。(write.cgiに直接アクセスしたら、test.datを書き出してくれるのに) 何か、根本的に間違ってるんでしょうか、、。 ちなみに、以上はwindows上で操作してます。

回答No.1

おっしゃりたいことはなんとなくわかりますが、もう少し具体的だといいと思 いますよ。 No.70723でご質問されていることから推測すると、「処理終了後」というのは、 CGIプログラムmyprog.cgiの処理が終わる直前に print "Location: http://my.provider.com/~myname/abc.cgi?a=123&b=xyz\n\n"; などと書いておき、パラメータa,bを渡してabc.cgiを呼び出すようにしようと しているのでしょうか。「GET方式」とはこのパラメータ指定方法のことですか? だとすると、abc.cgiがGETではなくPOSTを解釈するように記述してあるとか、 なんらかの理由でこのパラメータ指定方法ではうまくいかないという状況なの でしょうね。 それならば、print "Location: ..."の代わりに、myprog.cgiの中でabc.cgiを 直接実行してしまえば良いと思います(abc.cgiもmyprog.cgiと同じサーバにあ ると仮定した話です。別のサーバにあるCGIプログラムを実行したいなら、socket で接続するとか、LWPモジュールを使うとか、ちょっと面倒なことになりますね)。 例えばパラメータがa=123&b=xyzとすると… $param = 'a=123&b=xyz'; $ENV{CONTENT_LENGTH} = length($param); $ENV{REQUEST_METHOD} = 'POST'; open(OTHER_CGI, "|./abc.cgi") or die "$!"; print OTHER_CGI $param; close(OTHER_CGI); POSTメソッドは標準入力でパラメータを受け取るのですから、パイプを使って 標準入力からパラメータを流し込んでやればいいわけです。myprog.cgiが httpサーバの振りをして、環境変数をうまくセットしてやって、まるで普通に サーバから呼び出されたかのようにしてやれば良いでしょう。 ただしこの場合、abc.cgiが "Content-type: text/html" などを出力して いる、いわゆるよくあるCGIプログラムの場合は、そのヘッダもそのまま出て しまいますね。これをフィルタリングしたい、となると、他のプログラムの 入力と出力を同時に処理するわけですから、IPC::Open2モジュールなどを使う ことになります。(自前でforkしてもいいですがいろいろと面倒です)。 まあ普通ここまでする前に、どちらのプログラムも自分で編集できるなら 共通部分をライブラリ(モジュール)として別ファイルにくくり出して、 abc.cgiもmyrog.cgiもそのライブラリを呼び出して自分の作業を行うように 改造するのが普通だと思います。 …推測だけでここまで書いてしまいましたが、ぜんぜん見当はずれだったら 申し訳ありません。いずれにせよ詳しい状況をお教えください。

defd
質問者

補足

どうも、うまくいきません。 一つ目のCGIから、二つ目のCGIを実行するには、 open(OTHER_CGI, "|./abc.cgi") or die "$!"; print OTHER_CGI $param; close(OTHER_CGI); これだけでよいのでしょうか。 二つ目のCGIはファイルを生成するものなのですが、動きませんでした。 CGIのなかから、他のCGIを実行させる、というのはやったことがないもので、、、

関連するQ&A