以下に、Node.jsと自由時間でこの問題をどのように解決したかを説明します。
私が最初にしたことは、Bitrixがファイル編集でどのように機能するかを調べることでした。 すべてが非常に単純であることが判明し、私の期待をまったく上回っていませんでした-ファイルのテキストは、ファイル名とともにフォームによってサーバーに送信され、そこでphpスクリプトは指定されたファイルを開いて内容を書き込みます。
私にとって最も論理的なことは、同じハンドラーへのフォームの送信をシミュレートすることでした。
このためには、次の3つのことを行う必要があります。
- ブラウザのふりをする
- ファイルを編集する権限を持つユーザーになりすます
- フォームを送信
httpプロトコルについて少なくとも少し知っている人なら誰でも、リクエストヘッダーのUser-Agent行がクライアントプログラムを定義する責任があることを知っています。
ここで、自分自身を偽装しているプログラムの署名を示す必要があります。 私はこれを持っています:
Mozilla/5.0 (Windows NT 6.1; WOW64; rv:22.0) Gecko/20100101 Firefox/22.0
もう少し複雑なのは、ユーザーになりすます状況です。 入力するか、Cookieを1つずつ削除することで、サイトがユーザーをログインしていると見なすには、ユーザー名と現在のphpsessidのみが必要であることがわかりました 。 ログインはすでに知っていますが、セッション番号を確認する方法はいくつかあります。
まず、任意のブラウザーで利用可能な「開発ツール」を使用して、簡単に見ることができます。
第二に、フォームを送信しているので、セッションの番号がクッキーの形で私たちに届くように、ログインフォームをその前にサイトに送信できます。
いずれにせよ、ファイルのダウンロードはサイトに入ることに関連しているため、最初の方法を使用することにしましたが、毎回FireBugを開く代わりに、サイトのページの1つにphpsessidの出力を追加しました。
最後に行う必要がある最も重要なことは、フォームからのようにデータをサーバーに送信することです。
複雑なこともありません。 同じリクエストヘッダーで、ヘッダーに添付されるコンテンツのタイプを決定するContent-Typeを指定し、サーバーが受け入れるコンテンツの量を知るために必要なContent-Lengthを追加します。
その後、リクエストの本文で、シリアル化されたデータを送信します。シリアル化されたデータは、ファイルのテキスト、サーバー上のファイル名、フォームプロセッサに必要な他の変数です。
「計算」が終了したので、練習に進むことができます。
まず、サーバーにファイルを正常にアップロードするために必要な一般情報を決定します。 指定されたログイン番号とセッション番号に加えて、ローカルマシン上のファイルへのパスと、これらのファイルが保存されるサーバー上のパスが必要です。
1つ目は、スクリプトを引数として渡し、他のすべての情報を、スクリプトに渡されるフォルダー内のファイルに保存することです。
nodejsでは、コマンドライン引数はグローバル変数processの argvフィールドに格納されます。引数がプログラムに渡されなくても、 process.argv配列にはまだ2行が含まれています-「node」と実行するプログラムの名前。まず、少なくともいくつかの引数がスクリプトに渡されたかどうかを確認し、突然それが判明しなければ、終了します。
if(process.argv.length<3){ console.log(" !"); process.exit(1); }
ローカルフォルダーへのパスを受け取ったら、そこにあるはずのconfig.jsonファイルを開きます。
fs(FileSystem)モジュールは、nodejs内のファイルを操作します。 nodejsのモジュールは本質的に単なる関数のセットですが、javascriptの関数が他の言語の関数とまったく同じではないことは誰もが知っています。
ご想像のとおり 、ファイルの内容を読み取る、ごく普通の関数fs.readFile(パス、コールバック)が必要です。 最初の引数ですべてが明確な場合、2番目はファイルが完全に読み取られたときに実行される関数です。 さらに、プログラムはこの時点を予期してフリーズすることはありませんが、実行を継続します。 プログラムを編成するこのアプローチは、イベント指向プログラミングと呼ばれます。 だから-私たちは指定されたフォルダ内の設定ファイルを読み取ります。 その内容は、2番目の引数としてコールバック関数に渡されます。 最初のエラーはエラー、またはすべてが正常であればfalseになります。
var fs = require('fs'); // , fs fs.readFile(process.argv[2]+'\config.json', function (err, data) { if (err) throw err; c = JSON.parse(data);// json //...- });
次に、フォルダー内のファイルのリストを取得し、各ファイルをサーバーにアップロードする必要があります(ただし、このファイルが構成ファイルまたは他の無視されるファイルでない限り)。
//... fs.readdir(process.argv[2],function(err,files){ // if (err) throw err; files.forEach(function(el,index,array){ if(el.split('.').length>1) if(el!='config.json' && el!='.git' && el!='.gitattributes' && el!='.gitignore') // upload(el); // }); });
ファイル名を受け取ったら、その内容を読み取ってサーバーに送信できます。 それが私たちのすることです。 httpリクエストを送信するために、nodejsにはhttpモジュールがあります。 接続したら、関数http.request(メソッド、パス、ポート、ホスト名、ヘッダー、コールバック)を呼び出すことができます。最後から2番目の引数は文字通り全能になります。これは、任意の見出しでリクエストを送信できるためです。コンテンツタイプをリクエストします。 リクエストを行うと、その動作に影響を与えることができる変数にそれを取得します。 たとえば、 write()およびend()メソッド。 リクエストボディでデータを送信しますが、書き込みを連続して数回呼び出すことができ、終了するのは1回だけです。 呼び出しの直後に、要求は完了します。
前述のように、データはシリアル化された形式で送信する必要があります。つまり、アドレスバーに表示されるとおりです。 Nodejsには、このようなデータを処理するためのモジュールがあり、クエリ文字列と呼ばれます。 オブジェクトを文字列に保存したり、その逆を行うことができます。 持っているすべてのフォームデータは、グローバル変数queryに保存され、後続の送信のためにシリアル化されます。
var http = require('http'); var querystring = require('querystring'); function upload(file){ console.log(" %s:",file); var fileData=fs.readFileSync(process.argv[2]+'\\'+file); // query.path=c.path+file;// query.filesrc=fileData.toString(); var str=querystring.stringify(query);// var len=str.length; var request = http.request( // { method:'post', path:'/bitrix/admin/fileman_file_edit.php', port:80, hostname:'***.****.ru', headers:{ 'host':'***.****.ru', 'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:22.0) Gecko/20100101 Firefox/22.0', 'Cookie':'PHPSESSID='+c.phpsessid+';BITRIX_SM_LOGIN='+c.login, 'Content-Type':'application/x-www-form-urlencoded', 'Content-Length':len } },rListener); // request.end(str); // ( ) }
ファイルがアップロードされたか、作品が無駄になったかを知るために、リクエストへの応答を受け入れます。 コールバックは応答の受信時に呼び出され、最初の引数はステータスを含むすべての応答情報を受け入れます。 すべて同じポーキング方法で、ファイルが正常にダウンロードされると、リダイレクトが応答し、それ以外の場合はページが応答することがわかりました。
function rListener(response){ var status=''; switch(response.statusCode){ case 302: status=' ';break; // - case 200: status=' ';break; default : status=''; } console.log('%s (%d).',status,response.statusCode); }
完全なスクリプトコードはこちらです。
このような自転車を持っている場合、お気に入りのエディターでキーを押すことでスクリプト呼び出しを設定するのは非常に簡単です。 このメモ帳++とNppExecプラグインがあります。