微框架Express,挺好用的
(是不是所有微框架长得都雷同啊……)
其实开头一段是基于net module建一个原始server,没涉及到express,原则上应该放到前一段,但是我懒了……所以……(不过这一段合起来其实就是自己写了一个简易版express,所以也可以啦)
需要修改:此段结构混乱,不忍直视……
需要增添:还在学session,估计和我原来接触过的其他框架差不多,学完了更新上来……
/************************************* Express ****************************************/
//Creating a Web server
//Request and response
const http = require('http');
http.createServer(handleRequest).listen(3000);
console.log('starting server on port 3000';
function handleRequest(req, res) {
if(req.url == '/') {
res.writehead(200, {'content-type':'text/plain'});
res.end('hello');
} else {
res.writeHead(404, {'Content-Type':'text/plain'});
res.end('Not Found');
}
}
//serveStatic
//1. attempted to read the contents of a file
//2. and when it finished, it would send back an HTTP response
function serveStatic(res, path, contentType, resCode) {
fs.readFile(path, function(err, data) {
if (err) {
res.writeHead(500, { 'Content-Type': 'text/plain' });
res.end('500 - Internal Error');
} else {
res.writeHead(resCode, { 'Content-Type': contentType });
res.end(data);
}
});
}
function handleRequest(req, res) {
if (req.url === '/') {
serveStatic(res, './public/index.html', 'text/html', 200);
} else if (req.url === '/about') {
serveStatic(res, './public/about.html', 'text/html', 200);
}
// remainder of function definition omitted for brevity
}
//A web framework is a set of tools, libraries or software that reduces the overhead of developing web applications.
//We're Using Express, a "minimal and flexible Node.js web application framework"
//Installing Express
npm install express
// if you don't already have a package.json
npm init
// install express and save dependency to package.json
npm install express --save
//Hello world
const express = require('express');
const app = express();
app.get('/', function(req, res){
res.send('hello');
});
app.listen(3000);
console.log('Started server on port 3000');
//express() - creates a new express application
//app.VERB(path, [callback]…, callback) - defines routes
//res.send([body]) - send a response
//res.set() - set a response header
//Serving Static Files
const path = require("path");
const publicPath = path.resolve(__dirname, "public");
app.use(express.static(publicPath));
//install handlebars
npm install hbs --save
//bring in handlebars
app.set('view engine', 'hbs');
//render a template
res.render('index', { "greeting":"HELLLOOOO" });
//in views/layout.hbs
<!-- surrounding html -->
{{{ body }}}
<!-- surrounding html -->
//in views/viewname.hbs
{{ greeting }} world!
//context Objects
// the second argument is an object
res.render('myview', {'item':'pizza', 'description':'tasty'});
<h3>{{ description }} {{ item }}</h3>
<h3>tasty pizza</h3>
//block expressions / helpers
//Looping Over Arrays
app.get('/templating-arrays', function(req, res) {
res.render('templating-arrays', {'luckyNumbers':[42, 7, 78, 3, 5]});
});
<ul>
{{#each luckyNumbers}}
<li>{{this}}</li>
{{/each}}
</ul>
//Arrays with Named Elements
{{#each words as |word|}}
<p>word again: {{word}}</p>
{{/each}}
//Also Works With Objects
app.get('/templating-objects', function(req, res) {
res.render('templating-objects', {'obj':{'topping':'mushroom', 'size':'medium'}});
});
/*
<ul>
{{#each obj}}
<li>{{this}}</li>
{{/each}}
</ul>
//key and values
{cat: {name:'bill furry', lives:9}};
<ul>
{{#each cat}}
<li>{{@key}}, {{this}}</li>
{{/each}}
</ul>
//Dealing with an Array of Objects
{points: [{x:1, y:2, z:3}, {x:21, y:34, z:55}]}
<ul>
{{#each points}}
<li>{{this}}, {{this.x}}, {{this.y}}, {{this.z}} </li>
{{/each}}
</ul>
<ul>
{{#each points}}
<li>{{x}}, {{y}}, {{z}}</li>
{{/each}}
</ul>
//Conditionals
<>
{{#if isActive}}
<img src="star.gif" alt="Active">
{{else}}
<img src="cry.gif" alt="Inactive">
{{/if}}
<>
*/
//if you see something like:
//Expecting 'ID', 'DATA', got 'INVALID'
//You probably have spaces in your {{ #helper }}
//Middleware
//middleware is just a function
//it's a function that has three parameters:
//1. a request object (usually req)
//2. a response object (usually res)
//3. and the next middleware function to be executed (conveniently called next)
//"An Express application is essentially a stack of middleware which are executed serially."
//using middleware
// for the whole application
app.use(yourMiddleWareFunction);
//or... for a specific path:
app.use('path', yourMiddleWareFunction);
//Middleware Functions are executed in the order of their inclusion!
//all together
const express = require('express');
const app = express();
app.use(function(req, res, next) {
console.log(req.method, req.path);
next();
});
app.use(function(req, res, next) {
console.log('hello');
next();
});
app.use(function(req, res, next) {
res.set('Server', 'MY AMAZING SUPER COOL SERVER');
next();
});
app.get('/', function(req, res) {
res.send('We\'re done here');
});
app.listen(3000);
//Using the Static File Middleware
const path = require('path');
const publicPath = path.resolve(__dirname, 'public');
app.use(express.static('public'))
//Body Parser
app.use(express.urlencoded({ extended: false }));
//URL
scheme/protocol - http
domain or actual ip address - pizzaforyou.com
port (optional) - 80 (default if http)
path - /search
query_string (optional) - ?type=vegan
fragment_id (optional) - #topresult
//scheme://domain:port/path?query_string#fragment_id
//GET
//GET requests usually don't have a body
//the data in a GET request is in the query string part of the URL
//any characters that have special meaning in a URL are replaced with a numeric reference prefixed by %
//POST
//the content or data that's being sent is placed in the body of the POST request
//the content-type header specifies what kind of content is contained in the body
//1. generally, POST bodies have a content-type of application/x-www-form-urlencoded, which is the same as url encoding a query string
//2. if the data is an image being uploaded, the content-type is multipart/form-data
//3. finally, if the data being POSTed is JSON, the content-type is application/json
//An Example Request
GET /about HTTP/1.1
Host: localhost:8080
Connection: keep-alive
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.124 Safari/537.36
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
//A Sample Response
HTTP/1.1 200 OK
Content-Type: text/html
Date: Tue, 07 Oct 2014 03:38:37 GMT
Connection: keep-alive
Transfer-Encoding: chunked
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="/css/base.css" type="text/css" media="screen">
</head>
<body>
<h1>Home</h1>
<p>This is the homepage!</p>
<img src="/img/image1.png">
</body>
</html>
//Request Object
//Properties
//Originally from node's http module:
/*
* req.url - path and querystring (no protocol, port, or domain)
* req.headers - object with request headers as property names and header values as property values
* req.method - request method (POST, GET, PUT, etc.)
*/
//Added by Express:
/*
* req.path - request path (without protocol, host, port, or querystring)
* req.query - an object containing query string parameters
* req.body - an object containing POST parameters (requires middleware to make available)
*/
//We'll also learn about req.route and req.params later in class
//Redirect
//301 - Moved Permanently… you should use the new URL to request this resource
//302 - Found (Moved Temporarily)… you should continue to request resource at this URL
//303 - See Other… the resource can't be retrieved with the request method used
//Response Object
/*
* res.status(status) - sends response with status code back, can be chained with send: res.status(200).send('hello')
* res.send(body), res.send(status, body) - sends a response back to the client with an optional status code (the default is 200)
* res.render(view, [locals], callback) - render a view using the locals object - the property names of the object are variables in the template
* res.redirect([status], url) - redirect to a specific page using an optional status (the default is 302)
* res.json(json), res.json(status, json) - sends json back as a response with an optional status code
* res.set(name, val) - you can still do stuff like manually set headers, or specify media type, but this functionality is usually for special cases
*/
//Form
const express = require('express');
const app = express();
app.set('view engine', 'hbs');
app.use(express.urlencoded({ extended: false }));
// this is middleware to log method and path
app.use(function(req, res, next) {
console.log(req.method, req.path);
next();
});
// oops, a global... ok for now...
const myName = '';
app.get('/', function(req, res) {
res.render('simple-form', {'myName':myName});
});
app.post('/', function(req, res) {
console.log(req.body);
// change the global
myName = req.body.myName;
res.redirect('/');
});
app.listen(8080);
<strong>Current value of "myName":</strong> {{myName}}
<form method="POST" action="/">"
Enter your name: <input type="text" name="myName">
<input type="submit">
</form>