npm start 持久化运行

  • 直接键入 which nohup

复制这个地址,默认是 /usr/bin/nohup

  • 编辑用户环境变量 vi ~/.bash_profile

于 PATH=$PATH:$HOME/bin

后面添加

PATH=$PATH:$HOME/bin:/usr/bin/nohup

  • 加载环境变量:source ~/.bash_profile

  • 执行启动命令:nohup npm start &

执行成功会看到进程 PID 提醒

[1] 17073

nohup: 忽略输入并把输出追加到”nohup.out”

原程序的的标准输出被自动改向到当前目录下的 nohup.out 文件,起到了 log 的作用

  • 停止进程:
1
2
3
ps -ef | grep npm
ps -ef | grep node
kill -9 17073

Discuz!报错问题汇总

1、解决 X3.2 全局 HTTPS 问题思路

购买 SSL 证书

购买适合自己论坛的 SSL 证书,证书大致上分为标准型 DV SSL 证书、企业型 OV SSL 证书以及增强型 EV SSL 证书。

在服务端 WEB 服务器配置

参考文档:点击具体查看各种 WEB 服务器配置

在后台配置全局 HTTPS

进入 admin.php 后台,点击全局 - 站点信息 - 网站 URL 填写 https://yourdomain.com/admin.php

修成 Discuz 适配 https

如果你的 Web 服务是 Apache,请忽略这一步,Nginx 请继续看

Discuz 判断网站是否启动 SSL 是采用 $_SERVER[‘HTTPS’] 的方式,此方法不支持 Nginx(nginx+php-fpm),需要先做一些修改,让 Discuz 使用 $_SERVER[‘SERVER_PORT’]来判断网站是否启用 SSL

进入安装 DIscuz 根目录右键修改 public_html/source/class/discuz/discuz_application.php

1
$_G['isHTTPS'] = ($_SERVER['HTTPS'] && strtolower($_SERVER['HTTPS']) != 'off') ? true : false;

修改为:

1
$_G['isHTTPS'] = ($_SERVER['SERVER_PORT'] == 443 || $_SERVER['HTTPS'] && strtolower($_SERVER['HTTPS']) != 'off') ? true : false;

进入安装 DIscuz 根目录继续修改 public_html/uc_server/avatar.php

1
define('UC_API', strtolower(($_SERVER['HTTPS'] == 'on' ? 'https' : 'http').'://'.$_SERVER['HTTP_HOST'].substr($_SERVER['PHP_SELF'], 0, strrpos($_SERVER['PHP_SELF'], '/'))));

修改为:

1
define('UC_API', strtolower(($_SERVER['SERVER_PORT'] == 443 || $_SERVER['HTTPS'] == 'on' ? 'https' : 'http').'://'.$_SERVER['HTTP_HOST'].substr($_SERVER['PHP_SELF'], 0, strrpos($_SERVER['PHP_SELF'], '/'))));

后台 Ucenter 通信使用 https 方式

若不更改亦可以,这一步可以忽略

进入 admin.php 后台,点击站长 - UCenter 设置 - UCenter 访问地址将 http 改为 https 其后将头像调用方式改为使用静态地址调用头像。

后台 Ucenter 无法通信

审查元素,观察 return error 然后去官方找到相应的解决方法。

修成 Discuz 文章 https

进入安装 DIscuz 根目录继续修改 public_html/source/function/function_core.php

<font style="color:#F5222D;">$content = output_replace($content);</font>代码下方处添加

<font style="color:#F5222D;">$content = str_replace('http://www.xxx.com','https://www.xxx.com',$content);</font>

如果你有二级目录请这样添加

<font style="color:#F5222D;">$content = preg_replace('http://(.*?)xxx.com','https://\1xxx.com',$content);</font>


2、X3.2 升级至最新 X3.4 总结

准备前置条件:

DiscuzX 程序版本:Discuz! X3.2 Release 20141225 DiscuzX

后台版本:UCenter 1.6.0 DiscuzX

最新版本下载地址:https://gitee.com/3dming/DiscuzL/attach_files

操作步骤:

1)备份数据库,导出转储 SQL 文件结构和数据;

2)备份服务端网站目录;

3)创建 old 新文件夹,除了 data , config , uc_client , uc_server 目录以外的文件夹均移动进入 old 新文件夹内,注意 old 文件夹为小写字母;

4)通过 ftp 上传最新的服务端文件,注意分清下载的最新版本编码对应服务器正在使用的编码;

5)关闭站点,关闭服务端 web 服务;

6)将上传完毕解压后的 upload 文件夹内所有文件复制并替换服务端网站目录。

7)上传 utility 目录中的 update.php 文件到 install 目录中,删除 install.php 文件,并确保 install/data 中的 sql 文件完整。

8)执行 https://yourwebsite/install/update.php 按步骤完成升级。

最后尝试访问网站是否有异常,使用管理员登录站点后台,更新缓存。步骤为:后台=>工具=>更新缓存,完成升级。

升级过程中遇到的问题:

1.如果选择“是”您的站点将恢复站点默认风格,则你原网站风格、SEO 和 logo 全部还原为原始模版风格,注意升级选择。

2.在升级后无法登录后台

先确定你的账号在数据库内是否为管理员或者被清空,如无问题再找到根目录下的 uc_server/model 目录里的 admin.php 文件,并搜索代码 <font style="color:#F5222D;">$this->cookie_status = 0;</font> 修改为 <font style="color:#F5222D;">$this->cookie_status = isset($_COOKIE['sid']) ? 1 : 0;</font> 即可。

3.在升级时候遇到错误 【SELECT skey FROM common_setting WHERE skey=’strongpw’ LIMIT 1】

遇到 SQL 问题可以尝试 SQL 语句执行一下,很明显可以确定到 1146 问题,没有该表。尝试 creat common_setting 表即可,遇到这个问题的,后续也可能会遇到 common_syscache 表缺少 和 common_member 缺失 realname 字段,这里建议核对一下。这里我创建字段时候,选择 varchar(25)

4.在升级的时候遇到错误【请手工执行以下升级语句 XXX】

遇到又是 SQL 问题,先确定是否 SQL 语句执行正常。然后判断逻辑,这里 update.php 其实是官方升级程序,通过改表的方式升级的一个 bug.多年未改,只干了改表的事和新建表的事,改完表后,原来不存在了,但程序里却在对该表进行查询操作,所以会报“表不存在”的错误,导致升级程序终止,不能继续升级。

解决方法,即注释 <font style="color:#F5222D;">if(!empty($oldcols[$key]))</font><font style="color:#F5222D;">... ADO PRIMARY KEY ...</font> 代码,刷新页面重新升级即可。

5.第一个步骤提示验证失败,无法进行升级

跳过第一个升级步骤,直接访问 https://yourwebsite/install/update.php?step=prepare 即可。

6.升级后发现许多地方乱码了

请核对字符编码为 UTF-8 简繁 还是 GBK


3、Discuz 开启 Redis

Windows 系统操作

参考 CentOS 操作步骤

CentOS 系统操作

1.查看 php 版本

1
2
3
[root@VM_0_2_centos ~]# php -v
PHP Warning: PHP Startup: Unable to load dynamic library '/usr/lib64/php/modules/redis.so' - /usr/lib64/php/modules/redis.so: undefined symbol: igbinary_unserialize in Unknown on line 0 PHP 5.6.40 (cli) (built: Jan 12 2019 09:19:57) Copyright (c) 1997-2016 The PHP Group Zend Engine v2.6.0, Copyright (c) 1998-2016 Zend Technologies with Zend OPcache v7.0.6-dev, Copyright (c) 1999-2016, by Zend Technologies
[root@VM_0_2_centos ~]#

2. 查看 php-redis 扩展包全名

<font style="color:#F5222D;">yum list | grep php56w*</font>

如果是其它版本就将修改“56”修改为其正确本版

3. 通过 yum 安装 redis 扩展

<font style="color:#F5222D;">yum -y install php56w-pecl-redis.x86_64</font>

4. 重启 httpd 服务

<font style="color:#F5222D;">service httpd restart</font>

5. Discuz 需要编译 Config/config_global.php 配置才可以开启,默认是不打开的。

<font style="color:#F5222D;">$_config['memory']['redis']['server'] = '127.0.0.1';</font>


4、Discuz 迁移数据至Flarum

参考以下方法

https://github.com/KeKe12030/DiscuzToFlarum

https://github.com/branchzero/discuz-flarum-adapter

https://github.com/samyex6/discuz-flarum-migration


5、Discuz 迁移数据至XenForo

DZ 和 XF 均是 BB 代码,存在可迁移可能性

于Nuxt中使用Vuex

1、何为 Vuex

Vuex  是一个专为  Vue.js  应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。

但是在 Nuxt.js  内置引用了  vuex  模块,所以不需要额外安装。

Nuxt.js  会尝试找到应用根目录下的  store  目录,无需配置 nuxt.config.js,如果该目录存在,它将做以下的事情:

引用  vuex  模块 将  vuex  模块 加到  vendors  构建配置中去 设置  Vue  根实例的  store  配置项

2、引用 Vuex

Nuxt.js  支持两种使用  store  的方式,你可以择一使用:

普通方式: store/index.js  返回一个  Vuex.Store  实例 模块方式: store  目录下的每个  .js  文件会被转换成为状态树指定命名的子模块 (当然,index  是根模块)

2.1 普通方式

使用普通方式的状态树,需要添加  store/index.js  文件,并对外暴露一个  Vuex.Store  实例:

1
2
3
import Vue from 'vue'; import Vuex from 'vuex'; Vue.use(Vuex); const store = ()
=> new Vuex.Store({ state: { count: 1 }, mutations: { add(state) { state.count
++; } } }) export default store;

在组件中就可以直接调用:<font style="color:#DD1144;background-color:#F6F6F6;"><span>{{$store.state.count}}</span><button </font>``[@click](https://github.com/click)``<font style="color:#DD1144;background-color:#F6F6F6;">="$store.commit('add')">+1</button></font>

2.2 模块方式

状态树还可以拆分成为模块,store  目录下的每个  .js  文件会被转换成为状态树指定命名的子模块

使用状态树模块化的方式,store/index.js  不需要返回  Vuex.Store  实例,而应该直接将  state、mutations  和  actions  暴露出来:

1
2
export const state = () => ({ scount: 0 }) export const mutations = {
addScount(state) { state.scount += 2 } } // 模块模式状态树

在页面组件调用:

<font style="color:#DD1144;background-color:#F6F6F6;"><span>{{$store.state.index2.scount}}</span> <button @click="$store.commit('index2/addScount')">+2</button></font>

3、规范案例

在 Nuxt 项目的 store 目录下新建一个 index.js 文件作为主入口,这样项目就启用了 vuex

1
2
3
4
import Vue from 'vue'; import Vuex from 'vuex'; import counter_add from
'./counter_add'; import filter from './filter'; Vue.use(Vuex); const store = ()
=> new Vuex.Store({ state: {}, mutations: {}, modules: { counter_add, filter }
}) export default store

其他的业务代码分模块来写,在 store 文件夹里再新建一个 filter.js 文件,在 index.js 中引入一下。

1
2
3
4
5
const state = ({ value: 'Hello World', list: [1, 2, 3, 4, 5] }); const getters =
{ include: (state) => (val) => { return state.list.indexOf(val) > -1; } } ;
const mutations = { SET_VALUE(state, value) { state.value = value; } }; const
actions = { async getInfo({state, commit}, val) { commit('SET_VALUE', val); } };
export default { namespaced: true, state, getters, actions, mutations };

这个文件中输出时候的 namespaced 属性,如果为 true 时,使用这个文件的方法时,需要标注 namespace,不写或为 false 时,则可以直接使用,这里建议使用 namespaced,因为大型项目可能有很多复杂的业务,可能命名冲突,使用 namespaced 可以把方法区分开,避免很多问题

__

现在,我们在 vue 文件中使用 vuex

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<template>
<section class="p-10">
<h1>{{ value }}</h1>
<h1>{{ result }}</h1>
<el-button type="danger" @click="change">点击</el-button>
</section>
</template>
<script>
import { mapState, mapMutations, mapActions, mapGetters } from "vuex";
export default {
data() {
return {
result: false,
};
},
computed: {
...mapGetters("filter", ["include"]),
...mapState({
value: (state) => state.filter.value,
}),
},
methods: {
...mapMutations("filter", ["SET_VALUE"]),
...mapActions("filter", ["getInfo"]),
change() {
this.result = this.include(1);
this.getInfo("你好");
this.SET_VALUE("HELLO");
},
},
mounted() {},
beforeDestroy() {},
};
</script>

在 vue 文件中,首先通过 import { mapState, mapMutations, mapActions, mapGetters } from ‘vuex’ 来引入我们需要的模块,按需引用,只需要引入本页面用到的模块即可

mapGetters 和 mapState 需要在页面的计算属性 computed 中引入, mapMutations 和 mapActions 需要在 methods 中引入,此时要注意模块的命名空间,如果 vuex 文件导出时标注了 namespaced,我们使用时也需要写出才可以找到,反之则不需要

首先是 mapState,使用 mapState 时,我有两种方法来取,两种方式都可以,这个方法是从 store 中取出这个变量,然后显示在此页面上,store 变动的话,此页面也会跟着动态改变

1.1 实例

1
...mapState({ value: state => state.filter.value })

1.2 实例

1
...mapState('filter', { value: state => state.value })

MapMutation 是更改 store 中状态的唯一方法,Vuex 中的 mutation 非常类似于事件:每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数

mapAction 类似于 mutation, 但是 Action 提交的是 mutation,而不是直接变更状态,Action 可以包含任意异步操作,我们一般把异步获取数据的方法都放在这里,然后在回调函数里使用 mutation 里的方法把异步获取的数据保存在 store 里,然后把 store 里的数据传到页面

4、使用 QS 库

axios 默认的 content-type 是 application/json  也就是 java 后端经常让你把参数放在 body 中的那种格式 传输的样式是  requestbody

1
{ name:xxx, age:xxx }

如果使用的 qs 进行序列化

那么 content-type 就是 application/x-www-form-urlencoded

也就是常说的表单提交

传输的样式是  formdata

1
name:xxx, age:xxx

总结,实际上 urlencoding 后是  <font style="color:#DD1144;background-color:#F6F6F6;">name=xxx&age=xxx</font>

ajax 请求的 get 请求是通过 URL 传参的(以?和&符连接),而 post 大多是通过 json 传参的。 qs 是一个库。里面的 stringify 方法可以将一个 json 对象直接转为(以?和&符连接的形式)。

5、FAQ

Q:Cannot assign to read only property ‘exports’ of object

请检查您的项目是否存在  module.exports = xyz  表达,因为 webpack 2 中不允许混用 import 和 module.exports