Fork me on GitHub
xiaojun's blog

  • Home

  • Tags

  • Archives

规范化Git合作流程

发表于 2019-03-11
| 字数: 3.5k

Commitizen

纵观那些 GitHub 上 star 很多的开源库,开发流程都是极其规范的,Commitizen 便是用来规范化 git 提交信息的一个好工具。

AP2yb6.png

commitizen 通常要与适配器一起使用,通俗点来说是需要一个 commit message 模板,目前主流的是符合 Angular 规范的 cz-conventional-changelog。

✨ 安装

1
2
3
npm i -g commitizen
npm i -g cz-conventional-changelog
echo '{ "path": "cz-conventional-changelog" }' > ~/.czrc

以上命令代表全局使用 cz-conventional-changelog 适配器,你也可以通过以下命令来局部安装适配器

1
2
3
4
# 这种方式是使用npm来安装
commitizen init cz-conventional-changelog --save-dev --save-exact
# 这种方式是使用yarn来安装
commitizen init cz-conventional-changelog --yarn --dev --exact

假如你已经全局安装了适配器,那么上面的命令会报 A previous adapter is already configured. Use –force to override,如它所说,只需要加上 --force 参数即可强制使用局部适配器,成功后会在本地局部安装 cz-conventional-changelog,并在 package.json 中写入以下内容

1
2
3
4
5
6
7
8
9
10
{
"devDependencies": {
"cz-conventional-changelog": "^2.1.0"
},
"config": {
"commitizen": {
"path": "./node_modules/cz-conventional-changelog"
}
}
}

🎉 使用

安装成功后即可通过命令 git-cz 来代替 git commit 进行提交了

AP6OPJ.png

git-cz 具有 git commit 一切参数,就像这样: git-cz -a

VSCode 用户可以安装一个 Visual Studio Code Commitizen Support 扩展以使用更友好的 commit 界面,
按下 F1,输入 conventional commit,效果如下

APgNpd.png根据步骤操作就 ok 了。


Standard Version

🎈 用途

  • 自动升级 version
  • 自动生成 changelog
  • 自动打 tag

每次更新版本后会自动将 package.json(et al.) 和 CHANGELOG.md 提交

必须确保 Commit Message 符合 Conventional Commits 规范哦!上面使用的 cz-conventional-changelog 是符合这个规范的。

Ai9KgJ.png

🎄 安装

这里我选择全局安装

1
npm i -g standard-version

方便起见,首先新增一个 npm run script

1
2
3
4
5
6
{
"version": "1.0.0",
"scripts": {
"release": "standard-version"
}
}

🎀 发布第一版

发布第一版时运行以下命令,这条命令不会修改版本号

1
2
3
npm run release -- -f
# or
standard-version -f

🎁 升级一个版本

1
2
3
npm run release
# or
standard-version

🎨 生成一个预发布版本

1
2
3
npm run release -- -p
# or
standard-version -p

会得到一个类似 1.0.1-0 1.0.1-1 … 这种版本
如果希望为预发布版本命名,可以通过 --prerelease <name> 指定名称。
例如,假设您的预发行版应该包含 alpha 前缀

1
2
3
npm run release -- -p alpha
# or
standard-version -p alpha

这将得到一个 1.0.1-alpha.0 版本

🎏 手动选择版本

APXW0U.png

standard-version 遵循 Semver 语义化版本规范,假如你上次 commit 时选择的是 fix,这时默认应该更新的是个 path 版本,如果你想手动选择版本,可以这样

1
2
3
npm run release -- -r minor
# or
standard-version -r 1.1.0

🏀 阻止 Git Hooks

当 release 后,程序会自动将修改后的 package.json 和 CHANGELOG.md 文件 commit 掉,所以当使用 pre-commit 这种钩子时候可能就会报错,可以通过 --no-verify 跳过检测

1
2
3
npm run release -- --no-verify
# or
standard-version -n

🔫 生命周期脚本

standard-version 支持一些生命周期脚本

  • prerelease: 发布之前
  • prebump / postbump: 版本号更新之前 / 之后
  • prechangelog / postchangelog: changelog 生成之前 / 之后
  • precommit / postcommit: package.json 和 changelog 文件提交之前 / 提交之后
  • pretag / posttag: 打 tag 之前 / 之后

就像这样,你可以在某个声明周期中偷摸做点事情 🤡

1
2
3
4
5
6
7
{
"standard-version": {
"scripts": {
"prebump": "echo 9.9.9"
}
}
}

changelog 中 issue 地址默认是 GitHub 上的,如果想修改成 Jira 的地址,可以通过 postchangelog 配合 replace 库来修改它的链接地址

1
2
3
4
5
6
7
{
"standard-version": {
"scripts": {
"postchangelog": "replace 'https://github.com/myproject/issues/' 'https://myjira/browse/' CHANGELOG.md"
}
}
}

你也可以跳过某些生命周期 (bump, changelog, commit, tag) ,假如不想它自动打 tag,你可以这样

1
2
3
4
5
6
7
{
"standard-version": {
"skip": {
"tag": true
}
}
}

🎠 Tag 前缀

默认打的 tag 前缀是 v,生成的 tag 都是类似 v1.0.0 这种,可以通过 -t 设置前缀

1
2
3
npm run release -- -t @scope/package\@
# or
standard-version -t @scope/package\@

生成的 tag 看起来像这样 @scope/packag[email protected]

😊 帮助

1
2
3
npm run release -- -h
# or
standard-version -h

更多

除此之外,还可以利用 husky + prettier eslint commitlint lint-staged 等工具进一步优化 git 流程,利用 husky 的 pre-commit 钩子,可以在 commit 之前处理一些事情,就像

  • 代码格式化
  • 代码校验
  • Commit Message 校验
  • …

判断addEventListener是否支持passive属性

发表于 2018-12-03
| 字数: 945

写法

先看一下 MDN 现在 addEventListener 的写法,传参变成了这样:

1
target.addEventListener(type, listener, { capture: Boolean, passive: Boolean, once: Boolean })

以前第三个参数是一个 Boolean 值,它决定是否为捕获模式,现在可以传入一个对象了

  • capture: 同以前一样,表示 listener 是在捕获阶段执行还是冒泡阶段执行
  • passive: 表示 listener 永远不会调用 preventDefault()。
  • once: 表示 listener 只会调用一次。

用处

看上去懵懵的,其实,总结一下就是 passive 主要是为了优化滑动性能而生,当 passive 设置为 true 时,会告诉浏览器你的 listener 中不会调用 preventDefault() 这个方法,从而浏览器会做一系列优化来提升滑动体验,从而使滑动更顺畅

什么时候使用它

当你的 listener 中不会调用 preventDefault() 方法时,都尽量使用它,如果你设置了 passive 为 true 并且你代码中还调用了 preventDefault() 方法,那么浏览器会抛出一个错误

不兼容怎么办

这个属性出来的比较晚,兼容性不太好,怎么检测浏览器是否支持该属性呢?这里有个方法

1
2
3
4
5
6
7
8
9
10
11
var passiveSupported = false

try {
var options = Object.defineProperty({}, 'passive', {
get: function() {
passiveSupported = true
}
})

window.addEventListener('test', null, options)
} catch (err) {}

当浏览器支持该属性时 passiveSupported 会被赋值为 true,这段代码简直是酷到没朋友 👽

如何模拟移动端触摸事件

发表于 2018-11-20
| 字数: 5.2k

一直不理解为什么 vant-ui 的 pc 端文档右侧 demo 可以响应 touch 事件,比如它的轮播图页面,源码上不是监听的 touch 事件吗?为什么 pc 端上却可以滑动,什么鬼???🧐 今天终于找到了他们封装的一些方法,我觉得这对我挺有用的,这里记录一下,源码来自于 https://github.com/youzan/vant-doc/blob/master/helper/touch-simulator.js

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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
/**
* 模拟移动端 touch 事件
*/

var eventTarget

// polyfills
if (!document.createTouch) {
document.createTouch = function(view, target, identifier, pageX, pageY, screenX, screenY) {
// auto set
return new Touch(
target,
identifier,
{
pageX: pageX,
pageY: pageY,
screenX: screenX,
screenY: screenY,
clientX: pageX - window.pageXOffset,
clientY: pageY - window.pageYOffset
},
0,
0
)
}
}

if (!document.createTouchList) {
document.createTouchList = function() {
var touchList = TouchList()
for (var i = 0; i < arguments.length; i++) {
touchList[i] = arguments[i]
}
touchList.length = arguments.length
return touchList
}
}

/**
* create an touch point
* @constructor
* @param target
* @param identifier
* @param pos
* @param deltaX
* @param deltaY
* @returns {Object} touchPoint
*/

var Touch = function Touch(target, identifier, pos, deltaX, deltaY) {
deltaX = deltaX || 0
deltaY = deltaY || 0

this.identifier = identifier
this.target = target
this.clientX = pos.clientX + deltaX
this.clientY = pos.clientY + deltaY
this.screenX = pos.screenX + deltaX
this.screenY = pos.screenY + deltaY
this.pageX = pos.pageX + deltaX
this.pageY = pos.pageY + deltaY
}

/**
* create empty touchlist with the methods
* @constructor
* @returns touchList
*/
function TouchList() {
var touchList = []

touchList['item'] = function(index) {
return this[index] || null
}

// specified by Mozilla
touchList['identifiedTouch'] = function(id) {
return this[id + 1] || null
}

return touchList
}

/**
* Simple trick to fake touch event support
* this is enough for most libraries like Modernizr and Hammer
*/
function fakeTouchSupport() {
var objs = [window, document.documentElement]
var props = ['ontouchstart', 'ontouchmove', 'ontouchcancel', 'ontouchend']

for (var o = 0; o < objs.length; o++) {
for (var p = 0; p < props.length; p++) {
if (objs[o] && objs[o][props[p]] === undefined) {
objs[o][props[p]] = null
}
}
}
}

/**
* only trigger touches when the left mousebutton has been pressed
* @param touchType
* @returns {Function}
*/
function onMouse(touchType) {
return function(ev) {
// prevent mouse events

if (ev.which !== 1) {
return
}

// The EventTarget on which the touch point started when it was first placed on the surface,
// even if the touch point has since moved outside the interactive area of that element.
// also, when the target doesnt exist anymore, we update it
if (ev.type === 'mousedown' || !eventTarget || (eventTarget && !eventTarget.dispatchEvent)) {
eventTarget = ev.target
}

triggerTouch(touchType, ev)

// reset
if (ev.type === 'mouseup') {
eventTarget = null
}
}
}

/**
* trigger a touch event
* @param eventName
* @param mouseEv
*/
function triggerTouch(eventName, mouseEv) {
var touchEvent = document.createEvent('Event')
touchEvent.initEvent(eventName, true, true)

touchEvent.altKey = mouseEv.altKey
touchEvent.ctrlKey = mouseEv.ctrlKey
touchEvent.metaKey = mouseEv.metaKey
touchEvent.shiftKey = mouseEv.shiftKey

touchEvent.touches = getActiveTouches(mouseEv)
touchEvent.targetTouches = getActiveTouches(mouseEv)
touchEvent.changedTouches = createTouchList(mouseEv)

eventTarget.dispatchEvent(touchEvent)
}

/**
* create a touchList based on the mouse event
* @param mouseEv
* @returns {TouchList}
*/
function createTouchList(mouseEv) {
var touchList = TouchList()
touchList.push(new Touch(eventTarget, 1, mouseEv, 0, 0))
return touchList
}

/**
* receive all active touches
* @param mouseEv
* @returns {TouchList}
*/
function getActiveTouches(mouseEv) {
// empty list
if (mouseEv.type === 'mouseup') {
return TouchList()
}
return createTouchList(mouseEv)
}

/**
* TouchEmulator initializer
*/
function TouchEmulator() {
fakeTouchSupport()

window.addEventListener('mousedown', onMouse('touchstart'), true)
window.addEventListener('mousemove', onMouse('touchmove'), true)
window.addEventListener('mouseup', onMouse('touchend'), true)
}

// start distance when entering the multitouch mode
TouchEmulator['multiTouchOffset'] = 75

new TouchEmulator()

直接引入该文件,pc 端就可以响应移动端的 touchstart、touchmove、touchend 事件了 ✨。

小技巧处理fixed定位后其它内容被覆盖的问题

发表于 2018-11-04
| 字数: 3k

我们知道当对一个元素设置了 position: fixed; 后,该元素会脱离文档流,下面的内容会顶上来,导致被内容被遮盖。常见的一个做法是设置下面内容的 padding 或 margin,虽然能达到效果,但是总归不完美,特别是当我们想封装一个组件给别人用的时候,还得让别人设置一下样式,这样岂不麻烦,所以就有了下面这个方法,以我封装的这个 vue header 组件为例

示例代码

template

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<div :class="classList">
<div class="i-nav-bar__inner">
<div class="i-nav-bar__left" @click="handleClickLeft">
<slot name="left">
<i class="i-nav-bar__arrow fa fa-fw fa-angle-left" v-if="leftArrow"></i>
<span class="i-nav-bar__text" v-if="leftText">{{ leftText }}</span>
</slot>
</div>
<div class="i-nav-bar__title">
<slot name="title">{{ title }}</slot>
</div>
<div class="i-nav-bar__right" @click="handleClickRight">
<slot name="right"></slot>
</div>
</div>
</div>

script

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
export default {
name: 'INavBar',
props: {
title: String,
leftArrow: Boolean,
leftText: String,
fixed: Boolean
},
computed: {
classList() {
return [
'i-nav-bar',
{
'i-nav-bar--fixed': this.fixed
}
]
}
},
methods: {
handleClickLeft(ev) {
this.$emit('click-left', ev)
},
handleClickRight(ev) {
this.$emit('click-right', ev)
}
}
}

style(scss)

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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
$height: 50px;

.i-nav-bar {
height: $height;
&__inner {
position: relative;
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.07);
height: $height;
background-color: #fff;
color: #4a4d5a;
}
&__left {
height: 100%;
position: absolute;
top: 0;
left: 10px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
&:active {
opacity: 0.5;
}
.i-nav-bar__arrow {
font-size: 25px;
margin-top: -1px;
}
.i-nav-bar__text {
font-size: 14px;
margin-left: -6px;
}
}
&__title {
max-width: 50%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
margin: 0 auto;
font-size: 16px;
color: #34495e;
}
&__right {
height: 100%;
position: absolute;
top: 0;
right: 10px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
&:active {
opacity: 0.5;
}
}
&--fixed {
.i-nav-bar__inner {
position: fixed;
z-index: 1;
top: 0;
left: 0;
width: 100%;
}
}
}

总结

外面套一个父元素,height 假设为 50px,然后我们对里面这个元素设置 position: fixed;,它的 height 也设置 50px,这样的话虽然里面脱离了文档流,但是父元素依然占据着空间,所以下面的元素也就不会顶上来,当别人使用你的组件时再也不用费力设置 padding 或 margin 了。

一些效果截图

图中头部是上面示例代码的效果图,tabbar 是我封装的另一个组件,这里为了演示效果,我把他们放到一起

5mWmzX.png

实现一个简单的Vuex状态持久化功能

发表于 2018-10-09
| 字数: 816

大多数人应该都遇到过 vuex 中 state 刷新后丢失的问题,这是因为 state 是存储在内存中的,刷新后当然就丢失了。
这里有个方案是每次更改 state 后把 state 存储在 localStorage 中,当初始化 vuex 时再从 localStorage 中取出。

使用 vuex 插件功能可以很方便实现上述方案

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// plugins/vuex-state-persister.js
export default function(store) {
const Key = '__VUEX_STATE__';
if (localStorage[key]) store.replaceState(JSON.parse(localStorage[Key]));
store.subscribe(function(mutation, state) {
localStorage.setItem(Key, JSON.stringify(state));
});
}
// store/index.js
import createStatePersister from '../plugins/vuex-state-persister';
// ...
export default new Vuex.Store({
// ...
plugins: [createStatePersister],
// 开发环境下启用严格模式,官方文档介绍:https://vuex.vuejs.org/zh/guide/strict.html
strict: process.env.NODE_ENV !== 'production'
});

以上只是一个简单实现,项目中建议使用 vuex-persistedstate

利用Git钩子实现自动部署

发表于 2018-09-28
| 字数: 739

当某些重要事件发生时,Git 以调用自定义脚本。有两组挂钩:客户端和服务器端。客户端挂钩用于客户端的操作,如提交和合并。服务器端挂钩用于 Git 服务器端的操作,如接收被推送的提交。

此教程的前提是要求你服务器上必须有个 git 仓库,创建 git 仓库的教程可以参考这篇文章
在CentOS7上搭建自己的Git服务器

以我的 git 仓库 /srv/GitLibrary/blog.git 为例

创建钩子脚本

1
2
3
cd /srv/GitLibrary/blog.git/hooks
# 创建钩子脚本,该脚本会在push完成后运行
vim post-receive

写入两句话

1
2
#!/bin/sh
git --work-tree=/srv/www/blog --git-dir=/srv/GitLibrary/blog.git checkout -f

然后

1
2
3
4
# 赋予可执行权限
chmod +x ./post-receive
# 设置所有者为git用户
chown -R git:git ./post-receive

过程很简单,总结一下:
当客户端 push 完成以后,紧接着远端仓库触发我们定义的钩子脚本,
那句命令会将 /srv/GitLibrary/blog.git 最新版本 checkout 到 /srv/www/blog 中。
你可以自定义这俩目录路径,但是需要注意一点的是该目录必须有写入权限,否则会因为没有权限导致部署失败。
可以使用 chmod 命令赋予权限,以我的文件夹 /srv/www/blog 为例

1
chmod -R 777 /srv/www/blog

OK,大功告成,当客户端 push 完成以后,最新代码就会自动部署到你指定的目录了。🎉🎉🎉

使用ul简单模拟一个在移动端上使用的Vue表格组件

发表于 2018-09-27
| 字数: 3.2k

感觉手动设置 table 样式挺恶心的,而且性能也很烂,今天用 ul + flexbox 简单模拟一个 vue 上用的

my-table.vue

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<div class="table">
<ul class="tr">
<li class="th" :style="styles(item)" v-for="item in columns" :key="item.key">{{item.title}}</li>
</ul>
<ul class="tr" v-for="(row, index) in data" :key="index">
<li
class="td"
:style="styles(item)"
v-for="item in columns"
:key="item.key"
v-html="item.render?item.render(row[item.key]):row[item.key]"
></li>
</ul>
</div>
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
export default {
props: {
columns: {
type: Array,
default() {
return []
}
},
data: {
type: Array,
default() {
return []
}
}
},
methods: {
styles(item) {
let { width, textAlign } = item
return {
width: (width || 100) + 'px',
textAlign: textAlign || 'left'
}
}
}
}
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
.table {
overflow: auto;
font-size: 0;

.tr {
display: inline-flex;
min-width: 100%;
border-bottom: 1px solid #a7bfda;

&:nth-child(2n) {
background-color: #d1dfec;
}

.th {
font-weight: bold;
}

.th,
.td {
display: inline-block;
padding: 10px 15px;
box-sizing: border-box;
flex-grow: 1;
font-size: 14px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
}
}

使用方式

1
<my-table :columns="tableColumns" :data="tableData"></my-table>
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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
import MyTable from '../components/table'
export default {
components: {
MyTable
},
data() {
return {
tableColumns: [
{
title: 'Name',
key: 'name',
width: 120
},
{
title: 'Age',
key: 'age',
textAlign: 'right',
render(val) {
if (val >= 18) {
return "<span style='color:green'>" + val + '</span>'
} else {
return "<span style='color:red'>" + val + '</span>'
}
}
},
{
title: 'Address',
key: 'address',
width: 250
}
],
tableData: [
{
name: 'John Brown',
age: 14,
address: 'New York No. 1 Lake Park',
date: '2016-10-03'
},
{
name: 'Jim Green',
age: 24,
address: 'London No. 1 Lake Park',
date: '2016-10-01'
},
{
name: 'Joe Black',
age: 30,
address: 'Sydney No. 1 Lake Park',
date: '2016-10-02'
},
{
name: 'Jon Snow',
age: 17,
address: 'Ottawa No. 2 Lake Park',
date: '2016-10-04'
}
]
}
}
}

Linux非交互式修改用户密码

发表于 2018-09-23
| 字数: 102

仅仅一句命令

1
echo "username:password" | chpasswd

例如

1
echo "root:123456" | chpasswd

成功以后不会有任何反应,但是实际上已经成功了。

Nginx配置阿里云免费SSL证书,咱也能用上HTTPS了

发表于 2018-09-22
| 字数: 1.3k

申请免费 SSL 证书

打开这个链接,品牌选择 Symantec,保护类型选择 1 个域名,证书类型选择免费型 DV SSL,域名个数选择 1 个,然后你就会发现费用只需要 0 元了 💪。

立即购买后需要选择补全信息,然后等待审批结果即可。

证书订单的流程如下:

补全信息 → 提交审核 → 查看进度 → 颁发证书 → 下载证书

注意:该证书的有效期只有一年

配置 nginx

找到已签发的订单,选择下载后会跳到教程页面,这里我再说明一下,以 nginx 为例

将证书下载下来,解压后里面有俩文件,不要修改里面的任何东西,
在 nginx 的安装目录下创建 cert 目录,将下载的证书丢进去,
然后修改配置文件内容,以我的配置为例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
server {
listen 443;
server_name xiaojun1994.top;
ssl on;
root /srv/www/blog;
index index.html;
ssl_certificate cert/215019006850496.pem;
ssl_certificate_key cert/215019006850496.key;
ssl_session_timeout 5m;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
location / {
}
}

以上属性中 ssl 开头的属性与证书配置有直接关系,其它属性请结合自己的实际情况复制或调整

最后,开启重定向功能,自动将 http 请求重定向到 https,有多种方式,这里说两种

1.

1
rewrite ^(.*)$  https://$host$1 permanent;

2.

1
2
3
if ($scheme = http ) {
return 301 https://$host$request_uri;
}

推荐使用第 2 种方式,因为我在使用百度站长平台 https 认证的时候它需要你把 http 重定向到 https,并返回 301 状态码。
但经过我测试以后发现 chrome 返回的是 307 状态码,原因未知,就不深追究了,应该是 chrome 为了安全做的措施吧

👻 别忘了重启 nginx

1
nginx -s reload

Nginx开启gzip

发表于 2018-09-21
| 字数: 492

查看 nginx 配置文件路径

1
nginx -t

修改配置文件

1
2
# 路径为第一步获取的那个
vim /etc/nginx/nginx.conf

在 http 区域中新增 gzip 配置

1
2
3
4
5
6
gzip              on;
gzip_min_length 1k;
gzip_comp_level 1;
gzip_types text/plain application/javascript application/x-javascript text/javascript text/xml text/css;
gzip_disable "MSIE [1-6]\.";
gzip_vary on;

逐行解释一下

  • 开启 Gzip
  • 大于 1K 的才压缩,一般不用改
  • 压缩级别,1-9,数字越大,压缩率越高,cpu 占用的也更多,我服务器比较渣,这里设置了 1
  • 进行压缩的文件类型
  • ie6 对 gzip 不怎么友好,就不给它压缩了
  • 添加 vary 响应头,给代理服务器用的

最后重启 nginx

1
nginx -s reload
123
xiaojun1994

xiaojun1994

23 posts
17 tags
GitHub
友链
  • 赖同学
  • John Stark
  • 胡雨
  • mghio
© 2019 xiaojun1994