oh-http

精解http

MIT License

Stars
206
Committers
2

http

jshttp

  • reqres
  • Chromehttp
  • httpGET/POST/
  • ajax
  • Node.js
  • postman
  • cUrl

reqres

HTTP

sessionhttp

Chromehttp

ChromeChromedebugChrome

  • cnodehttp
  • cnodeetag

http

HTTPTCPWebHTTP80user agentHTMLorigin servertunnel

TCP/IPHTTPHTTPHTTPTCP/IPTCP

HTTP80TCPHTTP"HTTP/1.1 200 OK"

Request Message

    • GET /images/logo.gif HTTP/1.1/imageslogo.gif
    • Accept-Language: en

HTTP/1.1Host

https://cnodejs.org/cnodeNetworkNetworkRequest Headersview source

url

URLuniform resource locatorwebURL

URL URL:

  1. () http://
  2. IP() 127.0.0.1:3000 www.baidu.com
  3. /photo/1.jpg

URL

https://cnodejs.org/topic/579391c32d740f7c26637e1b?a=1&b=2

path

http://127.0.0.1:3000/topic?a=1

http/query/app-2.js

const Koa = require('koa');
const app = new Koa();

// response
app.use(ctx => {
  if (ctx.path === '/topic') {
   ctx.body = ' Hello Koa ' + ctx.path + ' a='+ ctx.query['a'];
  }
  
   ctx.body = ' Hello Koa with default path = ' + ctx.path  ;
});

app.listen(3000);
$ node query/app-2.js

http://127.0.0.1:3000/topic?a=1

Hello Koa /topic a=1

http://127.0.0.1:3000/?a=1

Hello Koa with default path = /

querystring

Koaquerystring

http/query/app.js

const Koa = require('koa');
const app = new Koa();

// response
app.use(ctx => {
  ctx.body = 'Hello Koa-' + ctx.query['a'];
});

app.listen(3000);

ctx.queryctx.request.queryctx.query === ctx.request.query

$ node query/app.js

http://127.0.0.1:3000/?a=1,Hello Koa-11``ctx.query['a']

ctx.queryget

http status code

HTTPserver header HTTPHTTP Status Code HTTP

  • 500 : 'Internal Server Error',
  • 403 : 'Forbidden',
  • 404 : 'Not Found',
  • 304 : 'Not Modified',
  • 200 : 'OK',

http://www.restapitutorial.com/httpstatuscodes.html

https://github.com/nodejs/io.js/blob/master/lib/_http_server.js

http verbs

verbs =

http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html

http

  1. GET
  2. POST POST/
  3. PUT
  4. DELETE
// respond with "Hello World!" on the homepage
app.get('/user:id', function (req, res) {
  res.send('Hello World!');
});

// accept POST request on the homepage
app.post('/user/create', function (req, res) {
  res.send('Got a POST request');
});

// accept PUT request at /user
app.put('/user/:id', function (req, res) {
  res.send('Got a PUT request at /user');
});

// accept DELETE request at /user
app.delete('/user/:id', function (req, res) {
  res.send('Got a DELETE request at /user');
});

nodeverbs https://github.com/jshttp/methods/blob/master/index.js

  • ctx.path
  • ctx.query querystring
  • ctx.body

/topic?a=1

  • ctx.path === '/topic'
  • ctx.query === '?a=1'

pathquery

21/topic,2/topic10100if/else

get

(http/get/app.js):

const Koa = require('koa');
const bodyParser = require ('koa-bodyparser');
const route = require('koa-router')();

const app = new Koa();

app.use(bodyParser());
app.use(require('koa-static')(__dirname + '/public'));

app.use(route.routes())
   .use(route.allowedMethods());
route.get('/topic', function (ctx, next) {
    ctx.body = 'Hello koa' + ctx.query['a'];
    console.log (ctx.query['vehicle']);
});

app.listen(3000);
$ node get/app.js

htmlhttp/public/get.html

<form method="GET" action="/topic">
  <input type="text" name="a" value='1'><br><br>
  <input type="radio" name="sex" value="male">Male<br><br>
  <input type="radio" name="sex" value="female">Female<br><br>
  <input type="checkbox" name="vehicle" value="Bike">I have a bike<br><br>
  <input type="checkbox" name="vehicle" value="Car">I have a car<br><br>
  <input type="submit" value="OK">
</form>

http://127.0.0.1:3000/get.html,OK,'/topic'GET

shell

Car

geturlquerystring

post

(http/post/app.js):

const Koa = require('koa');
const bodyParser = require ('koa-bodyparser');
const route = require('koa-router')();

const app = new Koa();

app.use(bodyParser());
app.use(require('koa-static')(__dirname + '/public'));

// routes definition
app.use(route.routes())
   .use(route.allowedMethods());

route.post('/toc/aaa', function (ctx, next) {
    ctx.body = ctx.request.body['a'];
    console.log (ctx.request.body['vehicle']);
});

app.listen(3000);
$ node post/app.js

htmlhttp/public/post.html

<form method="POST" action="/toc/aaa">
  <input type="text" name="a" value='1'><br><br>
  <input type="radio" name="sex" value="male">Male<br><br>
  <input type="radio" name="sex" value="female">Female<br><br>
  <input type="checkbox" name="vehicle" value="Bike">I have a bike<br><br>
  <input type="checkbox" name="vehicle" value="Car">I have a car<br><br>
  <input type="submit" value="OK">
</form>

http://127.0.0.1:3000/post.html'/toc/aaa'POST

OK

posturlquerystring

$ npm install --save koa-multer

Koa

(http/uploads) (http/app.js)

const Koa = require('koa');  // v2
const router = require('koa-router')(); // v6
const multer = require('koa-multer');

const app = new Koa();
const upload = multer({ dest: 'uploads/' });
app.use(require('koa-static')(__dirname + '/public'));
app.use(router.routes())
    .use(router.allowedMethods());

router.post('/profile', upload.single('upfiles'),function (ctx, next){
    ctx.body = "upload is success";
});

app.listen(3000);

see more https://github.com/koa-modules/multer https://github.com/expressjs/multer

$ node app.js

html(http/public/upload.html)

<form method="POST" action="/profile" enctype='multipart/form-data'>
  <input type="file" name="upfiles">
  <input type="submit" value="OK">
</form>

http://127.0.0.1:3000/upload.html

ajax

ajax

AjaxAsynchronous Javascript And XMLJavaScriptXMLXMLHttpRequestXHRXHRDOMXMLAjaxXMLJSON

XMLHttpRequest

  • ajax

  • ajax

  • ajax

  • domcss

helloworld

$ cd ajax/helloworld
$ ls
ajax_info.txt index.html
$ hs . -p 9090 -o 
Starting up http-server, serving .
Available on:
  http://127.0.0.1:9090
  http://192.168.1.105:9090
Hit CTRL-C to stop the server
[Thu May 26 2016 22:32:54 GMT+0800 (CST)] "GET /" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36"
[Thu May 26 2016 22:32:55 GMT+0800 (CST)] "GET /favicon.ico" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36"
[Thu May 26 2016 22:32:55 GMT+0800 (CST)] "GET /favicon.ico" Error (404): "Not found"
  • hs nodehttp-serverhttp

  • -p 9090

  • -o

  • ajax_info.txt

  • index.html

index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset='uft-8' />
    <title> ajax hello world </title>
  </head>  
<body>
  <div id="demo"><h2>AJAX</h2></div>
  <button type="button" onclick="send_ajax_request()"></button>

  <script>
    function send_ajax_request() {
      var xhr = new XMLHttpRequest();
      xhr.onreadystatechange = function() {
        if (xhr.readyState == 4 && xhr.status == 200) {
          // dom
          document.getElementById("demo").innerHTML = xhr.responseText;
          // style
          document.getElementById('demo').style.background = "lightblue";
        }
      };
      xhr.open("GET", "ajax_info.txt", true);
      xhr.send();
    }
  </script>
</body>
</html>

  • ajax

onclicksend_ajax_request()

<button type="button" onclick="send_ajax_request()"></button>
  • ajaxrequest
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
    if (xhr.readyState == 4 && xhr.status == 200) {
       ...
    }
};
xhr.open("GET", "ajax_info.txt", true);
xhr.send();

XHRopen()

void open(
   DOMString method, //"GET", "POST", "PUT", "DELETE"
   DOMString url,
   optional boolean async,
   optional DOMString user,
   optional DOMString password
);

ajaxsend

xhr.send();
  • ajaxresponse
if (xhr.readyState == 4 && xhr.status == 200) {
          // dom
          document.getElementById("demo").innerHTML = xhr.responseText;
          // style
          document.getElementById('demo').style.background = "lightblue";
        }

onreadystatechange

readyState onreadystatechange readyState XMLHttpRequest

readyState XMLHttpRequest 0 4 onreadystatechange 5 0 - 4 readyState

  • 0:
  • 1:
  • 2:
  • 3:
  • 4:

statushttp

  • 500 : 'Internal Server Error',
  • 403 : 'Forbidden',
  • 404 : 'Not Found',
  • 304 : 'Not Modified',
  • 200 : 'OK',

onreadystatechange

readyState 4 200 response

  • domcss

dom

document.getElementById("demo").innerHTML = xhr.responseText;

css

document.getElementById('demo').style.background = "lightblue";

response()

XMLHttpRequest responseText responseXML

  • xhr.responseText

  • xhr.responseXML XML

  • xmlxhr.responseXML

  • textxhr.responseText

  • jsonxhr.responseText

ajaxxxmlxmlweb servicejson

apiApplication Programming Interfacejson

json api

$ cd book-source/http/ajax/json
$ hs . -p 9091 -o
$ ls
data.json  index.html
  • data.json json
  • index.html

data.json

{
  "content": "ajax_info"
}

index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset='uft-8' />
    <title> ajax with json </title>
  </head>  
<body>
  <div id="demo"><h2>AJAX</h2></div>
  <button type="button" onclick="send_ajax_request()"></button>

  <script>
    function send_ajax_request() {
      var xhr = new XMLHttpRequest();
      xhr.onreadystatechange = function() {
        if (xhr.readyState == 4 && xhr.status == 200) {
          // json parse
          var data = JSON.parse(xhr.responseText)
          // dom
          document.getElementById("demo").innerHTML = data.content;
          // style
          document.getElementById('demo').style.background = "lightblue";
        }
      };
      xhr.open("GET", "data.json", true);
      xhr.send();
    }
  </script>
</body>
</html>

text

1)"data.json"

xhr.open("GET", "data.json", true);

2xhr.responseTextjsondomcss

if (xhr.readyState == 4 && xhr.status == 200) {
    // xhr.responseTextjson
    var data = JSON.parse(xhr.responseText)
    // dom
    document.getElementById("demo").innerHTML = data.content;
    // style
    document.getElementById('demo').style.background = "lightblue";
}

ajax

getpostactionajax

  • ajax

ajax

GET POST

POST GET

POST

  • POST
  • POST GET

koademo2

  1. npm initpackage.json

$ npm i -S koa@next
$ npm i -S koa-static@next

package.json2

"dependencies": {
    "koa": "^2.0.0",
    "koa-static": "^3.0.0"
}
  1. app.js
$ touch app.js

app.js

var serve = require('koa-static');
var Koa = require('koa');
var app = new Koa();

// httpserver
app.use(serve(__dirname + '/public'));

// json
app.use(ctx => {
  if (ctx.path === '/api/json') {
    ctx.body = {
      "content": "ajax_info"
    }
  } else {
    ctx.body = {
      "error": " /api/json "
    }
  }
});

app.listen(3000);

console.log('listening on port 3000');
  • httpserver

4

$ node app.js 
listening on port 3000

http://127.0.0.1:3000/api/json

// 20160527073015
// http://127.0.0.1:3000/api/json

{
  "content": "ajax_info"
}

https://github.com/typicode/json-server

get

getquerystring

if (ctx.path === '/api/get_json_with_param') {
    console.log(ctx.query)
    var name = ctx.query.name
    ctx.body = {
        "content": "ajax_info",
        "name": name
    }
}

http://127.0.0.1:3000/api/get_json_with_param?name=i5ting

post

koapostbodyparser

npm i -S koa-bodyparser@next

app.js

var serve = require('koa-static');
var bodyParser = require('koa-bodyparser');
var Koa = require('koa');
var app = new Koa();

// post
app.use(bodyParser());

// httpserver
app.use(serve(__dirname + '/public'));

post

if (ctx.path === '/api/post_json_with_param') {
    console.log(ctx.request.body)
    var name = ctx.request.body.name
    ctx.body = {
        "content": "ajax_info",
        "name": name
    }
}

getposturlchromepostmanpostx-www-form-urlencoded

koagetpostjson apiapiajaxjson api

ajax https://github.com/nodeonly/minAjax.js/blob/master/index.js

jQuery ajax

jQuery

zeptojQueryjQ

jQuery AJAX HTTP Get HTTP Post HTMLXML JSON - jQueryAJAX AJAX AJAX jQuery AJAX

AjaxjQuery<script src="jquery.js"></script>

jQuery

$.get("test.cgi", { name: "John", time: "2pm" }, function( data ) {
    // ajax
    alert( "Data Loaded: " + data );
    // domcss
    $(sss).html().css()
});
  • $.get$.postajaxxhr
  • function( data ) {}ajax
  • $(sss).html().css()domcss

https://github.com/DevMountain/mini-ajax

jQuery Ajax Ajax Ajax

app.js

var koa = require ('koa');
var serve = require ('koa-static');
var bodyParser = require ('koa-bodyparser');

var app = new koa();

app.use (bodyParser());
app.use (serve(__dirname + '/public'));
app.use ( ctx => {
    if(ctx.path === '/api/get_json_with_param'){
        console.log(ctx.query);
        var name = ctx.query.name;
        ctx.body = {
            "content":"ajax_info",
            "name": name
        }
    } else if (ctx.path === '/api/post_json_with_param') {
        console.log(ctx.request.body)
        var name = ctx.request.body.name
        ctx.body = {
            "content": "post_json_with_param",
            "name": name
        }
    } else {
        ctx.body = {
            "error":" /api/json "
        }
    }
});

app.listen(3000);

console.log ("listening on port 3000");
$node app.js

$.get$.postajax

5

  • ajax
  • dom
  • ajax
  • ajax
  • domcss

jQuery

<head>
    <meta charset='uft-8' />
    <title> ajax with json </title>
    <script src="/script/jquery.js"></script>
</head> 

get

$.get(url,[data],[callback])

  • url (String) URL.
  • data (Map)() Key/value QueryStringURL
  • callback (Callback) () (Responsesuccess)
  <form> 
    <input type='text' name='username' value='i5ting' id='myname'/>
    <div id="demo"><h2>AJAX</h2></div>
    <button id="bt1" type="button">get</button>
    <button id="bt2" type="button">post</button>
  </form>
  <script>
      $('#bt1').click( function () {  // ajax
          var name1 = $("#myname").val(); // 
            console.log(name1);  // 
            $.get ('/api/get_json_with_param', {name:name1}, function (data,status) {
            // function (data,staus)datastatus
             
            $('#demo').html("get" + data.name).css('background','lightblue');
            console.log (data); // 
         });
       });
  </script>

post

$.post(url,[data],[callback],[type])

$.get()

  • url (String) URL.
  • data (Map)() Key/value
  • callback (Callback) () (Responsesuccess)
  • type (String) () xml,text,json,jsonjson $.get()
  <form> 
    <input type='text' name='username' value='i5ting' id='myname'/>
    <div id="demo"><h2>AJAX</h2></div>
    <button id="bt1" type="button">get</button>
    <button id="bt2" type="button">post</button>
  </form>
  <script>
    $('#bt2').click( function () {
       var name1 = $("#myname").val();
       console.log(name1);
       $.post ('/api/post_json_with_param', {name:name1},function (data,status) {
          $('#demo').html("post" + data.name).css('background','red');
          console.log (data); // 
      });
    });
  </script>

Node.js

req3

expressjs4.x3

  • req.params
  • req.body
  • req.query

api

  • req.param(Deprecated. Use either req.params, req.body or req.query, as applicable.)

req.params

app.get('/user/:id', function(req, res){
  res.send('user ' + req.params.id);
});

req.body

Contains key-value pairs of data submitted in the request body. By default, it is undefined, and is populated when you use body-parsing middleware such as body-parser and multer.

This example shows how to use body-parsing middleware to populate req.body.

var app = require('express')();
var bodyParser = require('body-parser');
var multer = require('multer'); 

app.use(bodyParser.json()); // for parsing application/json
app.use(bodyParser.urlencoded({ extended: true })); // for parsing application/x-www-form-urlencoded
app.use(multer()); // for parsing multipart/form-data

app.post('/', function (req, res) {
  console.log(req.body);
  res.json(req.body);
})

req.bodypostexpressbodyParserreq.body

3post

req.query

queryquerystring

req.queryget

// GET /search?q=tobi+ferret
req.query.q
// => "tobi ferret"

// GET /shoes?order=desc&shoe[color]=blue&shoe[type]=converse
req.query.order
// => "desc"

req.query.shoe.color
// => "blue"

req.query.shoe.type
// => "converse"
// POST /search?q=tobi+ferret
{a:1,b:2}
req.query.q
// => "tobi ferret"

postreq.body

var app = express();
var multer  = require('multer')

// for raw data
app.use(function(req, res, next){
  if (req.is('text/*')) {
    req.text = '';
    req.setEncoding('utf8');
    req.on('data', function(chunk){ req.text += chunk });
    req.on('end', next);
  } else {
    next();
  }
});

app.use(multer({ 
	dest: './uploads/',
  rename: function (fieldname, filename) {
    return filename.replace(/\W+/g, '-').toLowerCase() + Date.now()
  }
}))
  • express4multer
  • express4req.text4

3post

var express = require('express');
var router = express.Router();

/* GET users listing. */
router.get('/', function(req, res) {
  res.send('respond with a resource');
});

router.get('/:id', function(req, res) {
  res.send('respond with a resource' + request.params.id);
});

router.post('/post', function(req, res) {
  // res.send('respond with a resource');
	res.json(req.body);
});

router.post('/post/formdata', function(req, res) {
  // res.send('respond with a resource');
	console.log(req.body, req.files);
	console.log(req.files.pic.path);
	res.json(req.body);
});

router.post('/post/raw', function(req, res) {
  // res.send('respond with a resource');
	res.json(req.text);
});


module.exports = router;

Post with x-www-form-urlencoded

see post.html

	<script>
	$(function(){
		$.ajaxSetup({
		  contentType: "application/x-www-form-urlencoded; charset=utf-8"
		});
	
		$.post("/users/post", { name: "i5a6", time: "2pm" },
		   function(data){
		     console.log(data);
		   }, "json");
		 
	});
	</script>

in routes/users.js

	router.post('/post', function(req, res) {
	  // res.send('respond with a resource');
		res.json(req.body);
	});

Post with form-data

npm install --save multer

Usage

var express = require('express')
var multer  = require('multer')

var app = express()
app.use(multer({ dest: './uploads/'}))

You can access the fields and files in the request object:

console.log(req.body)
console.log(req.files)

Multer will not process any form which is not multipart/form-data

see more

Post with raw

To get the raw body content of a request with Content-Type: "text/plain" into req.rawBody you can do:

https://gist.github.com/tj/3750227

req.rawBodyreq.text

tj

var express = require('./')
var app = express();
 
app.use(function(req, res, next){
  if (req.is('text/*')) {
    req.text = '';
    req.setEncoding('utf8');
    req.on('data', function(chunk){ req.text += chunk });
    req.on('end', next);
  } else {
    next();
  }
});
 
app.post('/', function(req, res){
  res.send('got "' + req.text + '"');
});
 
app.listen(3000)

http

var request = require('supertest');
var express = require('express');

var app = express();

app.get('/user', function(req, res) {
  res.status(200).json({ name: 'tobi' });
});

request(app)
  .get('/user')
  .expect('Content-Type', /json/)
  .expect('Content-Length', '15')
  .expect(200)
  .end(function(err, res) {
    if (err) throw err;
  });

ui

https://github.com/assaf/zombie

const Browser = require('zombie');

// We're going to make requests to http://example.com/signup
// Which will be routed to our test server localhost:3000
Browser.localhost('example.com', 3000);

describe('User visits signup page', function() {

  const browser = new Browser();

  before(function(done) {
    browser.visit('/signup', done);
  });

  describe('submits form', function() {

    before(function(done) {
      browser
        .fill('email',    '[email protected]')
        .fill('password', 'eat-the-living')
        .pressButton('Sign Me Up!', done);
    });

    it('should be successful', function() {
      browser.assert.success();
    });

    it('should see welcome page', function() {
      browser.assert.text('title', 'Welcome To Brains Depot');
    });
  });
});

    • ()
  • ava
    • gulp
    • promisethunksgeneratorasync
    • mock
    • api
    • model
    • zombie
    • cucumber
    • 90 Automating shapes smarter future.
    • ci
      • jenkinsci
      • travis-ci

postman

http

cUrl

#! /bin/bash

echo -n "post common"
curl -d "a=1&b=2" http://127.0.0.1:3001/users/post

echo -n 'post formdata'
curl -F 'pic=@"img/post-common.png"' -F 'a=1' -F 'b=2'  http://127.0.0.1:3001/users/post/formdata

echo -n 'post raw json'

curl -d "{"a":"1","b":"2","c":{"a":"1","b":"2"}}" http://127.0.0.1:3001/users/post

man curl.

more

TODO

web

    1. web server
    • node http
    • connect
    • express
    1. http-request
    • postman
    • vscode debug
    • req
    1. http-response
    • Expires Cache-Control
    • ETags
    • Gzip
    • Cookie
  • 04
    • CDN
    • HTTP
    • DNS
    • JavaScript CSS

webperformace