47

node.js サーバーに送信される投稿リクエストを処理しようとしています。server.js という名前の JavaScript ファイルは、ブラウザーにフォームを表示します。node.js バックエンドにポストされた後、フォームの値にアクセスしたい。

フォームには、ユーザー名、リポジトリ、およびブランチが含まれています。フォームが送信されたら、このデータをユーザーに表示したいと思います。

server.js コード:

var http = require('http');

http.createServer(function (request, response) {
response.writeHead(200, {'Content-Type': 'text/html'});
response.end('<html><body>'
    + '<h1>XYZ Repository Commit Monitor</h1>'
    + '<form method="post" action="." enctype="application/x-www-form-urlencoded"><fieldset>'
    + '<div><label for="UserName">User Name:</label><input type="text" id="UserName" name="UserName" /></div>'
    + '<div><label for="Repository">Repository:</label><input type="text" id="Repository" name="Repository" /></div>'
    + '<div><label for="Branch">Branch:</label><input type="text" id="Branch" name="Branch" value="master" /></div>'
    + '<div><input id="ListCommits" type="submit" value="List Commits" /></div>'
    + '</fieldset></form>'
    + '</body></html>');
}).listen(8124);

console.log('Server running at http://127.0.0.1:8124/');
4

1 に答える 1

157

あなたが提供したコードを使用し、遠い未来の人々に対応するために、あなたの質問でカバーされているものよりも詳細な回答を提供します. また、「Vanilla JS」( http://www.vanilla-js.com/ )を使用する回答も提供します。なぜなら、これがどのように機能するかを学ぼうとしているときに「フレームワークを使用する」と言う流行に敏感な人が多すぎると思うからです。彼らがそうする理由は、これがどのように機能するかを学んでいたときに、誰かが彼らに「フレームワークを使用する」ように言ったからだと思います. 彼らはハッカーではないため、プロセスを理解しようとはしませんでした。そのため、多くの場合、彼らの多くは、フレームワークなしで自分でこれを行う方法を理解していません (したがって、どこにでもある「フレームワークを使用する」ということになります)。何を理解することで、あなたはより良いハッカーになるでしょう。

出力しているフォームを介して POST (フォーム) データを受け取りたいので、サーバーにルーティング メカニズムを提供する必要があります。これは、サイトを訪れた人にフォームを提供するようにサーバーに指示することを意味しますが、ユーザーがフォームを送信すると、Node は POST データを小さな処理機能にルーティングします。コードから学びたい人に対応するために、最初に完全な回答を提供してから、さらに詳しく分析しました。

var http = require('http');
var qs = require('querystring');
var formOutput = '<html><body>'
  + '<h1>XYZ Repository Commit Monitor</h1>'
  + '<form method="post" action="inbound" enctype="application/x-www-form-urlencoded"><fieldset>'
  + '<div><label for="UserName">User Name:</label><input type="text" id="UserName" name="UserName" /></div>'
  + '<div><label for="Repository">Repository:</label><input type="text" id="Repository" name="Repository" /></div>'
  + '<div><label for="Branch">Branch:</label><input type="text" id="Branch" name="Branch" value="master" /></div>'
  + '<div><input id="ListCommits" type="submit" value="List Commits" /></div></fieldset></form></body></html>';
var serverPort = 8124;
http.createServer(function (request, response) {
  if(request.method === "GET") {
    if (request.url === "/favicon.ico") {
      response.writeHead(404, {'Content-Type': 'text/html'});
      response.write('<!doctype html><html><head><title>404</title></head><body>404: Resource Not Found</body></html>');
      response.end();
    } else {
      response.writeHead(200, {'Content-Type': 'text/html'});
      response.end(formOutput);
    }
  } else if(request.method === "POST") {
    if (request.url === "/inbound") {
      var requestBody = '';
      request.on('data', function(data) {
        requestBody += data;
        if(requestBody.length > 1e7) {
          response.writeHead(413, 'Request Entity Too Large', {'Content-Type': 'text/html'});
          response.end('<!doctype html><html><head><title>413</title></head><body>413: Request Entity Too Large</body></html>');
        }
      });
      request.on('end', function() {
        var formData = qs.parse(requestBody);
        response.writeHead(200, {'Content-Type': 'text/html'});
        response.write('<!doctype html><html><head><title>response</title></head><body>');
        response.write('Thanks for the data!<br />User Name: '+formData.UserName);
        response.write('<br />Repository Name: '+formData.Repository);
        response.write('<br />Branch: '+formData.Branch);
        response.end('</body></html>');
      });
    } else {
      response.writeHead(404, 'Resource Not Found', {'Content-Type': 'text/html'});
      response.end('<!doctype html><html><head><title>404</title></head><body>404: Resource Not Found</body></html>');
    }
  } else {
    response.writeHead(405, 'Method Not Supported', {'Content-Type': 'text/html'});
    return response.end('<!doctype html><html><head><title>405</title></head><body>405: Method Not Supported</body></html>');
  }
}).listen(serverPort);
console.log('Server running at localhost:'+serverPort);

そして今、なぜ私がしたことをしたのかを説明する内訳です.

var http = require('http');
var qs = require('querystring');

まず、実際のフォーム データを解析するために Node の組み込みの「クエリ文字列」モジュールを追加します。

var formOutput = '<html><body>'
  + '<h1>XYZ Repository Commit Monitor</h1>'
  + '<form method="post" action="/inbound" enctype="application/x-www-form-urlencoded"><fieldset>'
  + '<div><label for="UserName">User Name:</label><input type="text" id="UserName" name="UserName" /></div>'
  + '<div><label for="Repository">Repository:</label><input type="text" id="Repository" name="Repository" /></div>'
  + '<div><label for="Branch">Branch:</label><input type="text" id="Branch" name="Branch" value="master" /></div>'
  + '<div><input id="ListCommits" type="submit" value="List Commits" /></div></fieldset></form></body></html>';
var serverPort = 8124;

ロジックが読みやすくなるため、フォーム出力をサーバー/ルーティング/フォーム処理メカニズムの上に移動しました。サーバーのリッスン ポート情報もここに移動しました。

http.createServer(function (request, response) {

(私は通常、この関数のパラメーターを「req」と「res」に短縮しますが、それは私の好みです。)

  if(request.method === "GET") {
    if (request.url === "/favicon.ico") {
      response.writeHead(404, {'Content-Type': 'text/html'});
      response.write(notFound);
      response.end();

ここに、簡単なルーティングの例を含めました。この場合、サーバーに「favicon.ico」のリクエストをリッスンさせます。このリクエストは、すべての主要なブラウザによるウェブページのほぼすべての初期リクエストと一緒に行われます。このファイルは、アクセスしている各 Web ページのタブに表示される小さなアイコンです。この目的のために、favicon を提供する必要はありませんが、いくつかの基本的なルーティング メカニズムを示すために、ファビコンのインバウンド リクエストを処理します。

    } else {
      response.writeHead(200, {'Content-Type': 'text/html'});
      response.end(formOutput);
    }

訪問者がデフォルトの GET メソッド (上記で処理した "favicon.ico" 以外) を使用してサーバー上の他のリソースをブラウザで参照すると、フォームが提供されます。

  } else if(request.method === "POST") {

それ以外の場合、訪問者が POST をサーバーに向けている場合、以前の GET 要求で取得したフォームを送信した可能性が非常に高くなります。

    if (request.url === "/inbound") {

ここでは、"/inbound" と呼ばれるインバウンド リクエストをリッスンしています。これは、上記の詳細が理解できれば、HTML フォームの "アクション" です。ご存知かもしれませんが、フォームの「アクション」は、フォーム データの送信先をブラウザに伝えます。

      var requestBody = '';
      request.on('data', function(data) {
        requestBody += data;
        if(requestBody.length > 1e7) {
          response.writeHead(413, 'Request Entity Too Large', {'Content-Type': 'text/html'});
          response.end('<!doctype html><html><head><title>413</title></head><body>413: Request Entity Too Large</body></html>');
        }
      });
      request.on('end', function() {
        var formData = qs.parse(requestBody);

これは少し混乱するように見えるかもしれませんが、そうではないことを約束します。POST リクエストは、クライアント ブラウザからマルチパート メッセージとして送信できます。フォーム内の数個の変数のような小さなものでは、これが表示されることはほとんどありませんが、処理するデータの量をスケーリングすると、これが表示されます。注意深い場合はif()、POST データの長さを尋ねるステートメントも表示されます。悪意のある人物がエンドレス ファイルをアップロードすることでサーバーを停止させることはできますが、私たちが行動を起こせばそうはなりません。これにより、POST データ本体が約 10 メガバイトに制限されますが、それに応じて調整する必要があります。これらのことを知っておくと、将来の頭痛を防ぐことができます。頭痛を起こしてほしくありません。

        response.writeHead(200, {'Content-Type': 'text/html'});
        response.write('<!doctype html><html><head><title>response</title></head><body>');
        response.write('Thanks for the data!<br />User Name: '+formData.UserName);
        response.write('<br />Repository Name: '+formData.Repository);
        response.write('<br />Branch: '+formData.Branch);
        response.end('</body></html>');
      });

ここでフォームデータを使用します。Javascript の性質上、これらの変数名は大文字と小文字を区別します (「username」ではなく「UserName」など)。もちろん、このデータでやりたいことは何でもできます (Node のイベント ループと非同期の性質を念頭に置いてください)。

    }
    response.writeHead(404, 'Resource Not Found', {'Content-Type': 'text/html'});
    return response.end('<!doctype html><html><head><title>404</title></head><body>413: Request Entity Too Large</body></html>');

if()ルーティングの例を続けるために、ここで実行したことは、まだ処理していない POST 要求に対して一般的な 404 "Not Found" 応答をクライアントに送信するステートメントの下にキャッチオールが含まれています。

  } else {
    response.writeHead(405, 'Method Not Supported', {'Content-Type': 'text/html'});
    return response.end('<!doctype html><html><head><title>405</title></head><body>405: Method Not Supported</body></html>');
  }
}).listen(serverPort);
console.log('Server running at localhost:'+serverPort);

そして今、奇妙なメソッドでリクエストを処理するためのコードを少し含めて、コードを完成させました。私が対処していないことがいくつかあります (関数構造、空のフォーム データなど) が、目的を達成する方法は実にたくさんあります。私の CS 教授の 1 人が何年も前に言ったように、プログラムをプログラムする方法はたくさんあるので、宿題を共有することで誰がカンニングをしているのかを簡単に知ることができます。

Express などの外部のサードパーティ ライブラリに依存する代わりに、組み込みモジュールを使用して Node で処理を行うことが、難解なプロセスや少し難しいプロセスではないことを、あなた (および他の誰か) が理解できることを願っています。これらのライブラリは世界でその場所を持っていますが、群れに従わないでください: コードについて十分な情報に基づいた決定を下してください。

于 2013-10-04T14:36:30.980 に答える