问题描述:最近用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);
});