1、node静态服务器
const { join, extname } = require('path')
const fs = require('fs')
const http = require('http')
// 定义一个mime类型对象
const mimes = {
'.js': 'application/javascript',
'.jpg': 'image/jpeg',
'.css': 'text/css',
'.html': 'text/html;charset=utf-8'
}
// 网站根目录 url地址中的 / => www目录
const webRoot = join(__dirname, 'www')
// req 是对象也是流 res是对象也是流
http.createServer((req, res) => {
if (req.url != '/favicon.ico') {
// 得到客户请求的pathname,并且做了缺省页的处理
let pathname = req.url === '/' ? '/index.html' : req.url
// 得到请求的对象服务器中真实的文件路径
let filepath = join(webRoot, pathname)
// 判断文件是否存在,如果不存在则返回404
if (fs.existsSync(filepath)) { // 文件存在
// 得到请求文件的扩展名
const ext = extname(filepath)
// 得到扩展名
const mime = mimes[ext]
// 设置响应头
res.setHeader('content-type', mime)
// 读取文件并给响应
res.end(fs.readFileSync(filepath))
} else {
res.statusCode = 404
res.end('not found')
}
}
}).listen(3000, '0.0.0.0')
2、动态服务
2.1、get获取数据
const http = require('http');
const url = require('url');
http.createServer((req, res) => {
// 获取地址栏中 query数据
let { query } = url.parse(req.url, true);
console.log(query);
}).listen(8080)
2.2、post获取数据
const http = require('http');
const queryString = require('querystring');
http.createServer((req, res) => {
let data = '';
// 数据接受中
req.on('data', res => {
data += res
});
// 数据传输结束了 接受到的所有数据
req.on('end', () => {
// post数据
let post = queryString.parse(data)
console.log(post);
});
}).listen(8080)
let postData = []
// 有数据流入
req.on('data', buffer => postData.push(buffer))
// 接受完毕
req.on('end', () => {
console.log(qs.parse(Buffer.concat(postData).toString()));
res.end('ok')
})
2.3、文件上传
const { join, extname } = require('path')
const fs = require('fs')
const http = require('http')
const { createGzip } = require('zlib')
const url = require('url')
const qs = require('querystring')
const mimes = require('./libs/mime')
// 网站根目录 url地址中的 / => www目录
const webRoot = join(__dirname, 'www')
// get数据获取
http.createServer((req, res) => {
let { pathname, query } = url.parse(req.url, true)
// post处理
if (req.method === 'POST') {
// 路由 post登录处理 流
if (pathname == '/upload') {
// 文件名称
let filename = Date.now() + extname(req.headers.filename);
// 实现文件上传
req.pipe(fs.createWriteStream(join(webRoot, 'uploads', filename)))
res.end(JSON.stringify({ code: 0, url: 'http://localhost:3000/uploads/' + filename }))
}
} else {
if (req.url != '/favicon.ico') {
// query,就是浏览器访问的get参数集合
pathname = pathname === '/' ? '/index.html' : pathname
// 得到请求的对象服务器中真实的文件路径
let filepath = join(webRoot, pathname)
if (fs.existsSync(filepath)) {
// 得到请求文件的扩展名
const ext = extname(filepath).slice(1)
// 得到扩展名
const mime = mimes[ext]
// 设置响应头
res.setHeader('content-type', mime)
// res.setHeader('Content-Encoding', 'gzip')
let html;
if ('html' === ext) {
html = fs.readFileSync(filepath, 'utf-8');
// html = html.replace('{{id}}', query.id)
html = html.replace(/\{\{\s*(\w+)\s*\}\}/g, (preg, match) => {
return query[match]
})
} else {
html = fs.readFileSync(filepath)
}
res.end(html)
// fs.createReadStream(filepath).pipe(createGzip()).pipe(res)
} else {
res.statusCode = 404
res.end('not found')
}
}
}
}).listen(3000, '0.0.0.0')
3、node路由
const { join, extname } = require('path')
const fs = require('fs')
const http = require('http')
const { createGzip } = require('zlib')
const url = require('url')
const qs = require('querystring')
const mimes = require('./libs/mime')
const router = require('./events/route')
// 订阅请求pathname事件
require('./router/login')
// 网站根目录 url地址中的 / => www目录
const webRoot = join(__dirname, 'www')
http.createServer((req, res) => {
let { pathname, query } = url.parse(req.url, true)
pathname = pathname === '/' ? '/index.html' : pathname
if (req.url != '/favicon.ico') {
if (!extname(pathname)) {
// 接口类型,使用事件定完成路由
router.emit(pathname, req, res)
} else {
// 得到请求的对象服务器中真实的文件路径
let filepath = join(webRoot, pathname)
if (fs.existsSync(filepath)) {
// 得到请求文件的扩展名
const ext = extname(filepath).slice(1)
// 得到扩展名
const mime = mimes[ext]
// 设置响应头
res.setHeader('content-type', mime)
let html;
if ('html' === ext) {
html = fs.readFileSync(filepath, 'utf-8');
html = html.replace(/\{\{\s*(\w+)\s*\}\}/g, (preg, match) => {
return query[match]
})
} else {
html = fs.readFileSync(filepath)
}
res.end(html)
} else {
res.statusCode = 404
res.end('not found')
}
}
}
}).listen(3000, '0.0.0.0')
4、跨域问题
同源策略
跨域问题的出现是由于浏览器保护的安全策略,用于限制一个origin的文档或者它加载的脚本如何能与另一个源的资源进行交互。它能帮助阻隔恶意文档,减少可能被攻击的媒介。
跨域的访问会带来许多安全性的问题,比如,cookie一般用于状态控制,常用于存储登录的信息,如果允许跨域访问,那么别的网站只需要一段脚本就可以获取你的cookie,从而冒充你的身份去登录网站,造成非常大的安全问题,因此,现代浏览器均推行同源策略。
4.1、jsonp解决跨域问题
<script>
function 函数(){}
</script>
<script src=’http://xxx.com:3000/?cb=函数名’></script>
4.2、cors解决跨域
// 通过设置响应头信息,来允许ajax跨域请求
// * 表示允许所有域名来跨域请求
// * 如果你所写为 * 则cookie将无法跨域
if (allowDomain.includes(req.headers.origin)) {
// res.setHeader('Access-Control-Allow-Origin', 'http://localhost:4000')
res.setHeader('Access-Control-Allow-Origin', req.headers.origin)
res.setHeader('Access-Control-Allow-Credentials', 'true')
res.setHeader('Access-Control-Allow-Methods', 'GET,POST,PUT,PATCH,DELETE,OPTIONS')
res.setHeader('Access-Control-Allow-Headers', 'username')
res.setHeader('Access-Control-Expose-Headers', 'uuuu')
}
res.setHeader('content-type', 'application/json;charset=utf-8')
res.setHeader('uuuu', 'admin888')
res.end(jsonFn(user))
//=================================================
//前端页面的请求
const xhr = new XMLHttpRequest()
document.cookie = 'name=abc;path=/'
xhr.open('put', 'http://localhost:3000/', true)
xhr.withCredentials = true;
xhr.setRequestHeader('username', 'aaa')
xhr.send()
xhr.onreadystatechange = () => {
if (xhr.readyState === 4 && xhr.status === 200) {
console.log(xhr.getResponseHeader('uuuu'))
console.log(xhr.responseText)
}
}
4.3、postMessage
// a.html 3000
<iframe src="http://localhost:4000/" frameborder="0" id="frame" onload="load()"></iframe>
<script>
function load() {
let frame = document.getElementById('frame')
frame.contentWindow.postMessage('aaa', 'http://localhost:4000')
}
window.onmessage = function (e) {
console.log(e.data)
}
</script>
//========================================================
// b.html 4000
<script>
window.onmessage = function (e) {
console.log(e.data)
e.source.postMessage('bbb', e.origin)
}
</script>