node JS起一个http服务

326 阅读3分钟

问题描述:最近用node js写了个接口服务,部署到服务器上,在服务器上通过localhost+端口就可以访问,但是换成ip+端口就一直提示无法访问,而且外部浏览器也无法访问。

原因:我把监听的地址写成了127.0.0.1,所以才造成了一个乌龙。。。。下边给出正确写法。

const express = require('express');
const app = express();
const path = require('path');
const mysql = require('mysql');
var bodyParser = require('body-parser');
// 文件上传插件
const multer = require('multer');
var uploader = multer({
    // dest: '/var/local/staticfile/' // 这里是要上传的静态资源目录
    dest: './logs/'
});
const baseurl = 'https://www.xxx.com'; // 域名(上传文件成功后拼接用)
// https服务用
const https = require('https');
const fs = require('fs');
// 写错误日志用
const winston = require('winston');
const {
    createLogger,
    format,
    transports
} = require('winston');
const {
    combine,
    timestamp,
    label,
    prettyPrint
} = format;
require('winston-daily-rotate-file');
// token部分
const jwt = require('jsonwebtoken'); // 加密用
const expressjwt = require('express-jwt'); // 解密用
const private_key = 'l6heqpOcrMbwfv/oY49WlwKBgCc1M7Rru+Mlid8haA9lt1vNXh/1EU/KgPxlOpJfJ/K+4zMAFp/fcw0Nx+YJlm'; // 密钥(加解密用)

// 创建application/x-www-form-urlencoded 编码解析
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));

// 下面是解决跨域请求问题
app.all('*', function(req, res, next) {
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Headers", "X-Requested-With");
    res.header('Access-Control-Allow-Headers', 'Content-Type');
    res.header('Access-Control-Allow-Headers', 'Authorization'); // 定义前端传token的字段(express-jwt固定的字段)
    res.header("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS");
    res.header('Access-Control-Allow-Credentials', true);
    res.header("X-Powered-By",' 3.2.1');
    res.header("Content-Type", "application/json;charset=utf-8");
    next();
});

// 连接数据库
const connection = mysql.createConnection({
    host:'xx.xx.xx.206', // 本地用(远程服务器地址)
    // host: '127.0.0.1', // 上线用
    user:'root',
    password:'123456',
    database: 'apidata'
});
connection.connect();

/**
 * 验证token
 * 要放在接口前,定义字段后
 * 前端传token的格式为(固定传参格式,不可修改)
 * headers: {
 *     Authorization: 'Bearer ' + sessionStorage.getItem('token')
 * }
 */
app.use(
  expressjwt({
    secret: private_key,
    algorithms: ['HS256']
  }).unless({
    path: ['/api/login'] // 白名单,除了这里的地址,其它接口都要验证
  })
);
app.use((err, req, res, next) => {
    if (err.status === 401) {
        res.json({
            code: err.status || 401,
            data: {},
            msg: err.name || '未登录!'
        })
        return;
    }
    next();
});

// 登录
app.post('/api/login', (req, res) => {
    const username = req.body.username;
    const password = req.body.password;
    const sql = 'select * from user where username ="' + username + '"and password="' + password + '"';
    connection.query(sql, (err, result) => {
        if (err) {
            res.json({
                code: err.code || 500,
                data: {},
                msg: err.message || '服务器错误!'
            })
        } else {
            if (result && result.length) {
                const token = jwt.sign({
                    username,
                    password
                }, private_key, { algorithm: 'HS256' });
                res.json({
                    code: 200,
                    data: {
                        token
                    },
                    msg: '登录成功!'
                });
            } else {
                res.json({
                    code: -1,
                    data: {},
                    msg: '用户名或密码错误!'
                })
            }
        }
    })
})

// 查
app.get('/api/getuserlist',(req, res) => {
    const sql = 'select * from user'; // 写你需要的sql代码,你要是不会写那我就真的没办法了
    connection.query(sql, (err, result) => {
        // console.log(req.user)
        if (err) {
            res.json({
                code: err.code || 500,
                data: {
                    items: result
                },
                msg: err.message
            })
        } else {
            res.json({
                code: 200,
                data: {
                    items: result
                },
                msg: '获取成功!'
            })
        }
        // 返回的数据需要转换成JSON格式
        // res.json(result);
    });
});

// 增
app.post('/api/adduser',(req, res) => {
    // console.log(req.body);
    const sql = 'insert into user (name, age, sex, url) values ("'+(req.body.name||"")+'", "'+(req.body.age||"")+'", "'+(req.body.sex||"")+'", "'+(req.body.url||"")+'")';
    connection.query(sql, (err, result) => {
        // console.log(result);
        if(err){
            res.json({
                code: err.code || 500,
                data: {},
                msg: err.message || '添加失败!'
            });
        } else {
            res.json({
                code: 200,
                data: {},
                msg: '添加成功!'
            });
        }
    });
});

// 改(注意,这里有个坑,就是字符串需要用引号引起来)
app.put('/api/edituser', (req, res) => {
    const sql = 'update user set name="'+(req.body.name||"")+'", age='+(req.body.age||"")+', sex="'+(req.body.sex||"")+'", url ="'+(req.body.url||"")+'" where id='+req.body.id;
    connection.query(sql, (err, result) => {
        if (err) {
            res.json({
                code: err.code || 500,
                data: {},
                msg: err.message || '修改失败!'
            });
        } else {
            res.json({
                code: 200,
                data: {},
                msg: '修改成功!'
            });
        }
    })
})

// 删
app.delete('/api/deluser', (req, res) => {
    const sql = 'delete from user where id=' + req.body.id;
    connection.query(sql, (err, result) => {
        if (err) {
            res.json({
                code: err.code || 500,
                data: {},
                msg: err.message || '删除失败!'
            })
        } else {
            res.json({
                code: 200,
                data: {},
                msg: '删除成功!'
            })
        }
    })
})

// 上传文件 这里的single('file')表示上传文件的名字,这里指定为file
app.post('/api/upload', uploader.single('file'), (req, res) => {
    const file = req.file;
    const extname = path.extname(file.originalname); // 获取后缀名
    const filepath = file.path; // 获取上传成功后的文件路径
    const filename = filepath + extname; // 上传之后的文件名称
    const urlarr = filename.split('/');
    // const resulr = baseurl + filename; // 本来拼接的地址
    const resurl = baseurl + '/staticfile/' + urlarr[urlarr.length - 1]; // 拼接好后的返回地址(这里的staticfile是nginx指定的静态文件夹的别名)
    // 文件重命名
    fs.rename(filepath, filename, err => {
        if (err) {
            res.json({
                code: 500,
                data: {},
                msg: err.message || '上传失败!'
            })
        } else {
            res.json({
                code: 200,
                data: {
                    url: resurl
                },
                msg: '上传成功!'
            })
        }
    })
})

// 收集错误日志
winston.createLogger({
    transports: [
        new winston.transports.Console(),
        new winston.transports.File({
            name: 'info_logger',  // log名称
            filename: 'logs/info.log',  // 日志记录文件地址
            level: 'info', // 设置log的类型
            json: false
        }),
        // 第二个logger,记录error级别的log
        new winston.transports.File({
            name: 'error_logger',
            filename: 'logs/error.log',
            level: 'error',
            json: false
        })
    ]
});
var transport = new(transports.DailyRotateFile)({
    filename: './logs/app-%DATE%.log',
    datePattern: 'YYYY-MM-DD-HH',
    maxSize: '20m',
    maxFiles: '14d',
    json: false,
    format: combine(
      label({
        label: 'right meow!'
      }),
      timestamp(),
      prettyPrint()
    ),
});
transport.on('rotate', function (oldFilename, newFilename) { });

// 开启服务
var server = app.listen(3001, '0.0.0.0', function () {
    var host = server.address().address;
    var port = server.address().port;
    console.log("地址为 http://%s:%s", host, port);
});