赞
踩
分析:
1.将环境变量文件.env.development名字改成.env.producation
2.将环境变量里面的环境地址都改成线上地址
//原来
VUE_APP_RES_URL=http://192.168.0.174:9000
VUE_APP_EPUB_URL=http://47.99.166.157/epub
VUE_APP_BASE_URL=http://192.168.0.174:8080
VUE_APP_BOOK_URL=http://47.99.166.157:3000
VUE_APP_EPUB_OPF_URL=http://47.99.166.157/epub2
VUE_APP_VOICE_URL=http://47.99.166.157:3000
//改
VUE_APP_RES_URL=http://47.99.166.157/book/res
VUE_APP_EPUB_URL=http://47.99.166.157/epub
VUE_APP_BASE_URL=http://47.99.166.157:3000
VUE_APP_BOOK_URL=http://47.99.166.157:3000
VUE_APP_EPUB_OPF_URL=http://47.99.166.157/epub2
VUE_APP_VOICE_URL=http://47.99.166.157:3000
3.调cnpm run build,构建完了会生成dist目录,
分析:如有警告就是文件大小过大,
需要配置vue.config,修改配置后再执行一次cnpm run build
configureWebpack:{
performance: {
hints:'warning',
//入口起点的最大体积
maxEntrypointSize: 50000000,
//生成文件的最大体积
maxAssetSize: 30000000,
//只给出 js 文件的性能提示
assetFilter: function(assetFilename) {
return assetFilename.endsWith('.js');
}
}
}
4.再次报console.log打印错误,可以直接点击左上方的find in path 搜索console.log,把console.log注释掉
5.打包编译后,点击阅读电子书,出现404错误,在read中获取电子书的路径拼错了,修改如下
this.setFileName(books.join('/')).then(()=>{
const url = process.env.VUE_APP_EPUB_URL + '/'+ this.fileName + '.epub'
this.initEpub(url)
1.在storeDetail组件中添加点击事件,addOrRemoveShelf,调用store.js中两个方法
需要把vuex中的数据进行更新
addOrRemoveShelf() { // 判断这本书是否在书架中 if(this.inBookShelf){ // 存在就删除,再异步保存 removeFromBookShelf(this.bookItem).then(()=>{ saveBookShelf(this.ShelfList) }else{ // 不在求添加 addToShelf(this.bookItem) } this.setShelfList(getBookShlef) //更新VUEX }, // 将次方法改为shelfList,两处 inBookShelf() { if (this.bookItem && this.shelfList) {
2.上述的删除书本和添加书本方法可能会多处使用,所以我们添加到store.js中
//添加书本方法 export function addToShelf(book) { //到书架中把书拿出来 let shelfList = getBookShelf() //去到最后一本书 shelfList = removeAddFromShelf(shelfList) book.type = 1 //要添加到最后,添加一个字段 shelfList.push(book) //添加 shelfList = computeId(shelfList) //重新计算id //最后再删除的添加进去 shelfList = appendAddToShelf(shelfList) saveBookShelf(shelfList) //保存 } //删除书本方法 export function removeFromBookShelf(book) { //获取书本 return getBookShelf().filter(item => { if (item.itemList) { //书架里是否有这本书 //删除 item.itemList = removeAddFromShelf(item.itemList) } //不相等就保留,相等就移除 return item.fileName !== book.fileName }) }
6.添加书架按钮状态获取,我们可以调用mixin中的getShelfList方法,到StoreDetail中的counted属性中调用,获取到书架数据,从而可以判断到该书是否在书架中
mounted() {
this.init()
//判断是否等于0时和,才刷新,解决性能消耗
if(!this.ShelfList || this.ShelfList.length === 0){
this.getShelfList()
}
}
7.前面把read的获取电子书的地址改动了以后,把分类地址删除了。现在在运行过程中出现报错。原因是在StoreDetail组件中获取分类是空,所以在readBook方法中把分类地址添加进去
readBook() {
this.$router.push({
path: `/ebook/${this.categoryText}|${this.fileName}`
})
},
//改为
path: `/ebook/${this.bookItem.categoryText}|${this.fileName}`
if(href){
if(href[1]===loc){
nav.pagelist.push(item)
}
}
1.建立一个数据库,数据库名book,字符集utf8 排序规则utf8_general_ci
2.到入第十章的book.sql数据表
3.还有cover和img主要存储了图书的封面数据,把它拷贝到resoures下载文件夹中。
4.把epub和epub2(是电子书解压以后的路径)也拷贝到resoures
1.在页面创建一个名为node-imooc-ebook的空项目;
2.创建app.js,然后初始化项目,npm init
3.安装express框架:cnpm i express -S
4.在Node中不能使用e6导入文件,所以导入express
解析:原理express源码中是一个暴露了一个function,返回了一个app,还是一个方法。app里有很多方法get
const express = require('express') const app = express() app.get('/', (req, res) => { res.send(new Date().toDateString()) }) //项目启动接口,用app.listen const server = app.listen(3000, () => { //通过回调函数获取返回值,host 是获取当前的ip地址 const host = server.address().address //监听的端口号 const port = server.address().port //启动成功输出的内容 console.log('server is listening at http://%s:%s', host, port) })
5.启动方法:1.node app.js
2.使用左上add Configuration,点+号,点击Node.js. Name写app,node parameters写app.js
调试直接就可以点击上方的甲虫
6.安装cnpm i mysql -S 然后导入mysql数据库。配置数据库
const mysql = require('mysql') //链接数据库 function connect() { return mysql.createConnection({ host: constant.dbHost, //本地localhost user: constant.dbUser, //root password: constant.dbPwd, //123456 database: 'book' }) } //再写一个接口 app.get('/book/list', (req, res) => { const conn = connect() //链接 //调用conn.query返回的对象,调用查询语句 conn.query('select * from book where cover!=\'\'', //err是否错误 (err, results) => { if (err) { //有错误 //向前台返回一个json对象 res.json({ error_code: 1, msg: '获取失败' }) } else { //成功 results.map(item => handleData(item)) const data = {} constant.category.forEach(categoryText => { data[categoryText] = results.filter(item => item.categoryText === categoryText) }) //成功了就返回提示 res.json({ error_code: 0, msg: '获取成功', data: data, total: results.length }) } //一定要把数据库链接关闭 conn.end() }) })
app.get('/book/home', (req, res) => { const conn = connect() conn.query('select * from book where cover != \'\'', (err, results) => { //获取长度 const length = results.length //返回的类表 const guessYouLike = [] //首页封面图片 const banner = constant.resUrl + '/home_banner2.jpg' const recommend = [] //推荐图书 const featured = [] //精选 const random = [] //随机图书 const categoryList = createCategoryData(results) const categories = [ //分类的数据 { category: 1, num: 56, img1: constant.resUrl + '/cover/cs/A978-3-319-62533-1_CoverFigure.jpg', img2: constant.resUrl + '/cover/cs/A978-3-319-89366-2_CoverFigure.jpg' }, { category: 2, num: 51, img1: constant.resUrl + '/cover/ss/A978-3-319-61291-1_CoverFigure.jpg', img2: constant.resUrl + '/cover/ss/A978-3-319-69299-9_CoverFigure.jpg' }, { category: 3, num: 32, img1: constant.resUrl + '/cover/eco/A978-3-319-69772-7_CoverFigure.jpg', img2: constant.resUrl + '/cover/eco/A978-3-319-76222-7_CoverFigure.jpg' }, { category: 4, num: 60, img1: constant.resUrl + '/cover/edu/A978-981-13-0194-0_CoverFigure.jpg', img2: constant.resUrl + '/cover/edu/978-3-319-72170-5_CoverFigure.jpg' }, { category: 5, num: 23, img1: constant.resUrl + '/cover/eng/A978-3-319-39889-1_CoverFigure.jpg', img2: constant.resUrl + '/cover/eng/A978-3-319-00026-8_CoverFigure.jpg' }, { category: 6, num: 42, img1: constant.resUrl + '/cover/env/A978-3-319-12039-3_CoverFigure.jpg', img2: constant.resUrl + '/cover/env/A978-4-431-54340-4_CoverFigure.jpg' }, { category: 7, num: 7, img1: constant.resUrl + '/cover/geo/A978-3-319-56091-5_CoverFigure.jpg', img2: constant.resUrl + '/cover/geo/978-3-319-75593-9_CoverFigure.jpg' }, { category: 8, num: 18, img1: constant.resUrl + '/cover/his/978-3-319-65244-3_CoverFigure.jpg', img2: constant.resUrl + '/cover/his/978-3-319-92964-4_CoverFigure.jpg' }, { category: 9, num: 13, img1: constant.resUrl + '/cover/law/2015_Book_ProtectingTheRightsOfPeopleWit.jpeg', img2: constant.resUrl + '/cover/law/2016_Book_ReconsideringConstitutionalFor.jpeg' }, { category: 10, num: 24, img1: constant.resUrl + '/cover/ls/A978-3-319-27288-7_CoverFigure.jpg', img2: constant.resUrl + '/cover/ls/A978-1-4939-3743-1_CoverFigure.jpg' }, { category: 11, num: 6, img1: constant.resUrl + '/cover/lit/2015_humanities.jpg', img2: constant.resUrl + '/cover/lit/A978-3-319-44388-1_CoverFigure_HTML.jpg' }, { category: 12, num: 14, img1: constant.resUrl + '/cover/bio/2016_Book_ATimeForMetabolismAndHormones.jpeg', img2: constant.resUrl + '/cover/bio/2017_Book_SnowSportsTraumaAndSafety.jpeg' }, { category: 13, num: 16, img1: constant.resUrl + '/cover/bm/2017_Book_FashionFigures.jpeg', img2: constant.resUrl + '/cover/bm/2018_Book_HeterogeneityHighPerformanceCo.jpeg' }, { category: 14, num: 16, img1: constant.resUrl + '/cover/es/2017_Book_AdvancingCultureOfLivingWithLa.jpeg', img2: constant.resUrl + '/cover/es/2017_Book_ChinaSGasDevelopmentStrategies.jpeg' }, { category: 15, num: 2, img1: constant.resUrl + '/cover/ms/2018_Book_ProceedingsOfTheScientific-Pra.jpeg', img2: constant.resUrl + '/cover/ms/2018_Book_ProceedingsOfTheScientific-Pra.jpeg' }, { category: 16, num: 9, img1: constant.resUrl + '/cover/mat/2016_Book_AdvancesInDiscreteDifferential.jpeg', img2: constant.resUrl + '/cover/mat/2016_Book_ComputingCharacterizationsOfDr.jpeg' }, { category: 17, num: 20, img1: constant.resUrl + '/cover/map/2013_Book_TheSouthTexasHealthStatusRevie.jpeg', img2: constant.resUrl + '/cover/map/2016_Book_SecondaryAnalysisOfElectronicH.jpeg' }, { category: 18, num: 16, img1: constant.resUrl + '/cover/phi/2015_Book_TheOnlifeManifesto.jpeg', img2: constant.resUrl + '/cover/phi/2017_Book_Anti-VivisectionAndTheProfessi.jpeg' }, { category: 19, num: 10, img1: constant.resUrl + '/cover/phy/2016_Book_OpticsInOurTime.jpeg', img2: constant.resUrl + '/cover/phy/2017_Book_InterferometryAndSynthesisInRa.jpeg' }, { category: 20, num: 26, img1: constant.resUrl + '/cover/psa/2016_Book_EnvironmentalGovernanceInLatin.jpeg', img2: constant.resUrl + '/cover/psa/2017_Book_RisingPowersAndPeacebuilding.jpeg' }, { category: 21, num: 3, img1: constant.resUrl + '/cover/psy/2015_Book_PromotingSocialDialogueInEurop.jpeg', img2: constant.resUrl + '/cover/psy/2015_Book_RethinkingInterdisciplinarityA.jpeg' }, { category: 22, num: 1, img1: constant.resUrl + '/cover/sta/2013_Book_ShipAndOffshoreStructureDesign.jpeg', img2: constant.resUrl + '/cover/sta/2013_Book_ShipAndOffshoreStructureDesign.jpeg' } ] //随机获取9本不同的书, randomArray(9, length).forEach(key => { //这个数组通过for来获取全部数组 //通过createGuessYouLike加工后,把数据再加入到guessYouLike中 guessYouLike.push(createGuessYouLike(createData(results, key))) }) //推荐图书,拿到三本图书 randomArray(3, length).forEach(key => { recommend.push(createRecommendData(createData(results, key))) }) //获取6本精选图书 randomArray(6, length).forEach(key => { //书普通图书,直接获取就好了 featured.push(createData(results, key)) }) //随机图书, randomArray(1, length).forEach(key => { //随机获取一本就好了 random.push(createData(results, key)) }) //把上面所定义的数据,都返回 res.json({ guessYouLike, banner, recommend, featured, categoryList, categories, random }) //断开链接 conn.end() }) })
2.首页api中需要实现随机数,添加一个方法.
测试时localhost:3000/book/home
//n是要几本书,l是一共有几本书
function randomArray(n, l) {
//保存到rnd的变量中
let rnd = []
for (let i = 0; i < n; i++) {
//向下取整,获取0到1之间的随机时,再*l,这样最大的数都不会大于l
rnd.push(Math.floor(Math.random() * l))
}
//返回
return rnd
}
3.创建createData
//根据results和key找到对应的书 function createData(results, key) { return handleData(results[key]) } //封装的 function handleData(data) { //对封面进行加工,不是http://开头的 if (!data.cover.startsWith('http://')) { //resUrl地址, data['cover'] = `${constant.resUrl}/img${data.cover}` } //其他的属性 data['selected'] = false data['private'] = false data['cache'] = false //是否缓存 data['haveRead'] = 0 //是否阅读 //返回 return data } //再创建本地地址resUrl
4.创建const.js模块来储存公用数据,然后再到app.js中把const模块引入
const resUrl = 'http://192.168.31.243:8081'
module.exports = {
resUrl,
}
//引入模块
const constant = require('./const')
6.创建createGuessYouLike方法给获取到的数据再次加工一下
function createGuessYouLike(data) { //随机生成,1-3的数字 const n = parseInt(randomArray(1, 3)) + 1 data['type'] = n switch (n) { case 1: //根据id是否为偶数,显示另外一种形式.简单算法 data['result'] = data.id % 2 === 0 ? '《Executing Magic》' : '《Elements Of Robotics》' break case 2: data['result'] = data.id % 2 === 0 ? '《Improving Psychiatric Care》' : '《Programming Languages》' break case 3: data['result'] = '《Living with Disfigurement》' data['percent'] = data.id % 2 === 0 ? '92%' : '97%' break } //返回数据 return data }
7.推荐图书加工
function createRecommendData(data) {
//随机生成
data['readers'] = Math.floor(data.id / 2 * randomArray(1, 100))
return data
}
8.添加通用数据const.jscategory
const category = [ 'Biomedicine', 'BusinessandManagement', 'ComputerScience', 'EarthSciences', 'Economics', 'Engineering', 'Education', 'Environment', 'Geography', 'History', 'Laws', 'LifeSciences', 'Literature', 'SocialSciences', 'MaterialsScience', 'Mathematics', 'MedicineAndPublicHealth', 'Philosophy', 'Physics', 'PoliticalScienceAndInternationalRelations', 'Psychology', 'Statistics' ] module.exports = { resUrl, category, }
9.修改handleData
function handleData(data) {
if (!data.cover.startsWith('http://')) {
data['cover'] = `${constant.resUrl}/img${data.cover}`
}
data['selected'] = false
data['private'] = false
data['cache'] = false
data['haveRead'] = 0
return data
}
1.把vue.config.js中的devServer都注释掉,和mock函数,和引入 的 4个组件,再去修改.env.development中的api,把BASE 修改成本地接口
VUE_APP_RES_URL=http://192.168.0.174:9000
VUE_APP_EPUB_URL=http://192.168.0.174:9000/epub
VUE_APP_BASE_URL=http://192.168.0.174:3000
VUE_APP_BOOK_URL=http://192.168.0.174:3000
VUE_APP_EPUB_OPF_URL=http://192.168.0.174:9000/epub2
VUE_APP_VOICE_URL=http://192.168.0.174:3000
2.报错,到node.js接口中解决跨域问题,引入库cnpm i -S cors
在app.js中引入
const cors = require('cors')
app.use(cors())
3.首页bulnn图(轮播图)没有加入进来,到app.js中把图加入
const banner = constant.resUrl + '/home_banner2.jpg'
4.修改图书少出的问题
function createCategoryData(data) { const categoryIds = createCategoryIds(6) const result = [] categoryIds.forEach(categoryId => { const subList = data.filter(item => item.category === categoryId).slice(0, 4) subList.map(item => { return handleData(item) }) result.push({ category: categoryId, list: subList }) }) //返回时过滤,如果itme.list小于4就不要了 return result.filter(item => item.list.length === 4) }
1.添加app.get方法
如果获取失败,第一步就查看查询语句是否有误,输出查看
app.get('/book/detail', (req, res) => { const conn = connect() //链接数据库 //获取图书参数 const fileName = req.query.fileName //查询,把获取到的图书参数传入查询 const sql = `select * from book where fileName='${fileName}'` //通过conn.query,来查询这个语言,然把结果放到results中 conn.query(sql, (err, results) => { if (err) { //失败 res.json({ //返回 error_code: 1, msg: '电子书详情获取失败' }) } else { if (results && results.length === 0) { //还是获取失败 res.json({ error_code: 1, msg: '电子书详情获取失败' }) } else {//成功 //获取第一本书,进行封装,加工 const book = handleData(results[0]) res.json({ //返回成功 error_code: 0, msg: '获取成功', data: book }) } } //关闭数据库 conn.end() }) })
1.主要是用在分类里面的电子书,里面主要是包含了树状结构
app.get('/book/list', (req, res) => { const conn = connect() //查找封面不为空的电子书 conn.query('select * from book where cover!=\'\'', (err, results) => { if (err) {//请求失败 res.json({ error_code: 1, msg: '获取失败' }) } else {//成功 //获取到结果,进行遍历 results.map(item => handleData(item)) //对象 const data = {} //对分类进行遍历,categoryText文本 constant.category.forEach(categoryText => { //categoryText作为kye,用filter赛选分类名称相同的电子书找出来 data[categoryText] = results.filter(item => item.categoryText === categoryText) }) res.json({ //成功 error_code: 0, msg: '获取成功', data: data, total: results.length //把筛选的内容返回 }) } conn.end() }) })
2.普通结构的list
app.get('/book/flat-list', (req, res) => { const conn = connect() conn.query('select * from book where cover!=\'\'', (err, results) => { if (err) { res.json({ error_code: 1, msg: '获取失败' }) } else { results.map(item => handleData(item)) res.json({ error_code: 0, msg: '获取成功', data: results, //不同的返回results total: results.length }) } conn.end() }) })
1.比较简单,直接返回一个数组就行,
因为没有数据,+号(添加书籍)按钮没有出现,所以我们要用json返回一个空的数组
app.get('/book/shelf', (req, res) => {
res.json({
bookList: []
})
})
1.到科大讯飞官方注册账号,点击控制台,然后点击右上角的创建新应用。
2.需要添加服务,添加在线语音合成
3.ip白名单,在线系统就需要把在线系统的ip输入进去,本地要拿到外网ip,这样才能调用。不然不能调用。
4.可以点击开发文档实现语音对接,语音合成
5.需要授权认证,
6.到node.js中创建voice模块,用来合成语音api。然后给app.js引入voice模块,创建一个api
const voice = require('./voice')
//这个方法很简单,只要把结果和传入,就能在模块中拿到
app.get('/voice', (req, res) => {
voice(req, res)
})
7.到voice创建接口
8.授权认证,x-Appid在我们注册时的id
最会一个需要apikey也在注册中
需要安装cnpm i -S js-base64库
cnpm i -S js-md5加密库
cnpm i -S qs 对字符串进行处理,让post请求称为,键值对形式
以上都是给xParam使用
cnpm i -S http 库给herad请求
const Base64 = require('js-base64').Base64 const md5 = require('js-md5') const qs = require('qs') const http = require('http') const mp3FilePath = require('./const').mp3FilePath const resUrl = require('./const').resUrl const fs = require('fs') //接收app传来的请求 function createVoice(req, res) { //需要传入两个参数,文本和语音 const text = req.query.text const lang = req.query.lang // const text = '测试科大讯飞在线语音合成api的功能,比如说,我们输入一段话,科大讯飞api会在线实时生成语音返回给客户端' // const lang = 'cn' cn代表中文 //中文 let engineType = 'intp65' //如果传入的是英文 if (lang.toLowerCase() === 'en') { //就修改引擎为英文 engineType = 'intp65_en' } //朗读的速度 const speed = '30' // const voiceParam = { auf: 'audio/L16;rate=16000', //返回的是语音格式 aue: 'lame', //音频才采样率 voice_name: 'xiaoyan', //人语音 speed, //速度 volume: '50', //音量 pitch: '50', //音高 engine_type: engineType, //引擎类型 text_type: 'text' //文本类型 } //认证部分 //先获取时间utc的时间,/1000就可以了 const currentTime = Math.floor(new Date().getTime() / 1000) //获取注册处的appId const appId = '5c04d087' //apiKey祖册中有 const apiKey = 'd42c864c47d91f468a70079aab059be5' //调用Base64.encode进行加密,再用stringify把上面的参数传入 const xParam = Base64.encode(JSON.stringify(voiceParam)) //封装三个参数进行加密 const checkSum = md5(apiKey + currentTime + xParam) //定义变量 const headers = {} //封装把参数传入变量 headers['Content-Type'] = 'application/x-www-form-urlencoded; charset=utf-8' headers['X-Param'] = xParam headers['X-Appid'] = appId headers['X-CurTime'] = currentTime headers['X-CheckSum'] = checkSum headers['X-Real-Ip'] = '127.0.0.1' //定义把文本传入,生成请求参数 const data = qs.stringify({ text: text }) //请求参数 const options = { host: 'api.xfyun.cn', path: '/v1/service/v1/tts', //科大讯飞地址,到接口地址查看 method: 'POST', headers } //调用http库请求 const request = http.request(options, response => { //到这可以测试 //创建mp3文件 let mp3 = '' //对结果进行处理 const contentLength = response.headers['content-length'] //将编码格式为二进制文件 response.setEncoding('binary') //通过response.on回调方法回调结果data response.on('data', data => { //拿到data是语音播放的文件,把data传换成mp3文件 mp3 += data //进度百分显示,用当前接收到长度/总长度 const process = data.length / contentLength * 100 //转化成保留两位小数 const percent = parseInt(process.toFixed(2)) // console.log(percent) }) //end的时候所有信息以及获取好了 response.on('end', () => { // console.log(response.headers) // console.log(mp3) //通过这判断类型 const contentType = response.headers['content-type'] //如果不是mp3就失败 if (contentType === 'text/html') { res.send(mp3) //直接显示报错 } else if (contentType === 'text/plain') { //报错,把结果返回前端 res.send(mp3) } else { //将文件保存,名字用当前时间作为名字 const fileName = new Date().getTime() //创建文件路径,到resource中穿件mp3文件夹,输出路径 const filePath = `${mp3FilePath}/${fileName}.mp3` //实际下载的路径 const downloadUrl = `${resUrl}/mp3/${fileName}.mp3` // console.log(filePath, downloadUrl) //通过fs写入,filePath路径,数据,文件类型 fs.writeFile(filePath, mp3, 'binary', err => { //返回 if (err) { res.json({ error: 1, msg: '下载失败' }) } else { res.json({//返回下载成功 error: 0, msg: '下载成功', path: downloadUrl }) } }) } }) }) //传入data request.write(data) //断开 request.end() } //返回请求内容 module.exports = createVoice
在const.js中加入mp3文件路径地址
mp3FilePath = '/root/nginx/upload/mp3'
1.打开git,复制一个仓库地址,
2.回到node.js中,调用git init初始化
3.点View>Wool Windows >version Control >browse。然后把四个文件选中,右键Add to vcs。在控制台右键commi 提交到到本地git仓库
4.建立一个.gitignore文件,排除掉一些不希望上传的文件,然后再次commi,把不需要的移除
5.到vcs>git >remots >
文件名和项目地址,再点击右边的斜上箭头,push
node_modules
.iml
.idea
1.注册账号,点击产品,选择云服务器ECS
2.购买服务器,选择地区,选择核数,单核最便宜17元,镜像选择wind.选6.9(64)
3.存储,选择40g
4.网络不是运维的不需要配置,公网宽度需要选择分配公网IP地址,选择1M固定带宽
5.安全组80窗口
6.系统配置:实例名称用来自定义,剩下的都可以不选
7.分组设置也可以不设置
8.购买期限,下单
购买成功后到管理控制台
1.等待启动…
2.点击升降配置设置密码,然后点击重启。
3.打开cmd控制台:把公网地址复制,输入
ssh root@106.15.231.180
4.点击yes ,输入密码
5.链接上去输入who查看
6.输入ssh-keygen -t rsa 生成公钥,三次y
7.找到公钥的位置 ssh-copy-id -i ~/.ssh/id_rsa.pub root@/106.15.12(公网地址)
8.出现Nub后就可以免密登录
9.出现Broken pipe服务器断开了
10.输入 vim/etc/ssh/sshd_config打开文件
11.选择ClientAliveInterval设置i30,为30秒链接一次服务器
12.改完后输入exit断开,
13.改完配置后需要输入service sshd restart生效,然后再输入exit断开
14.再输入ssh root@imooc链接
1.复制指这段话,到服务器环境中执行,然后输入ll .nvm可以查看是否安装成功
2.输入nvm可以查看是否有效,无效输入vim .bashrc查看是否在这个文件,在这个文件输入source .bashrc 来讲环境变量生效,再输入nvm就可以生效
3.通过nvm install node来安装最近的版本
4.再安装cnpm 进入官方查找
npm install -g cnpm --registry=https://registry.npm.taobao.org
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。