服务端
一个Node.js HTTP服务端的基本代码骨架如下:
const http = require('http')
http.createServer((req, res) => {
// url是完整路径
const url = new URL(req.url, 'http://localhost:8080')
// url.host 主机+端口
// url.pathname: 路径
// url.searchParams : 查询端口
// POST请求触发data,参数data是请求体,使用toString()将二进制流转为字符串
req.on('data',data=>console.log(data.toString()))
// req.headers: 请求头对象
// req.setHeader('name','value') // 设置响应头
// 解决跨域问题
res.setHeader("Access-Control-Allow-Origin", "*")
res.end('res body') // 返回数据
}).listen('8080', () => console.log('running on http://localhost:8080'))
通常使用req,res表示请求对象和响应对象,这是惯用的写法。
请求的URL包括三大部分:
- 主机名+端口
- 路径,例如
- 查询参数
req.url只包括路径和查询参数,而调用new URL()需要传入完整的URL,因此需要补上主机名+端口:
const url = new URL(req.url, ' http://localhost:8080')
此时,就可以分别得到路径和查询参数了:
console.log(url.pathname) // 路径
console.log(url.searchParams) // 查询参数,是一个可迭代对象。
解析请求体需要监听req对象的data事件,得到请求体:
req.on('data',data=>console.log(data.toString()))
由于安全原因,HTTP服务器默认不能跨域访问,如果在浏览器script脚本中使用fetch()方法会被拒绝访问。要解除这个限制,可以添加一行如下代码:
res.setHeader("Access-Control-Allow-Origin", "*")
要返回数据,会用到两个方法:res.write()和res.end()。res.write()可以重复调用,表示不断开连接的情况下多次返回。而一旦遇到了res.end(),就会在返回这一次的数据后立即断开。如下示例表示返回了三次数据后断开连接:
res.write('hello')
res.write('world')
res.end('res end')
客户端
在Node.js和浏览器环境中均可使用fetch()发送HTTP请求、接收服务器响应,语法相同。
基本示例如下:
const url = 'http://localhost:8080/path1/path2/?key1=value1&key2=value2'
const req = {
method: 'POST',
headers: new Headers({}),
body: 'req body'
}
fetch(url, req)
.then(res => res.text()) // 如果服务器返回JSON对象,则为json()
.then(result => console.log(result))
请求方法有两种:GET和POST,如果要携带正文(即请求体),应使用POST方法。
请求头使用new Headers()初始化,然后就可以传入对象了,例如:
new Headers({'Content-Type' : 'text/plain'})
请求体是一个JavaScript对象,包括method、headers、body三个属性。其中,headers属性的是是一个Headers对象。
const req = {
method: 'POST',
headers: new Headers({})
body: 'req body'
}
fetch()函数返回的是一个期约对象,首先使用then()方法取出请求体,然后再使用then()方法打印请求体,如下示例:
fetch(url, req)
.then(res => res.text())
.then(result => console.log(result))
上面示例中的res对象还可以有如下属性和方法:
- status,取得返回码,如200。
- statusText,取得返回码状态,例如OK。
- headers,取得响应头。
- body, 取得响应体,这是一个ReadableStream对象。
- json(),如果响应体是一个JSON对象,使用该方法可以直接解析为JavaScript对象。