-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathsearch.xml
More file actions
1031 lines (496 loc) · 398 KB
/
search.xml
File metadata and controls
1031 lines (496 loc) · 398 KB
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
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<?xml version="1.0" encoding="utf-8"?>
<search>
<entry>
<title>EGG 安全问题</title>
<link href="/passages/20201018EGG%E5%AE%89%E5%85%A8%E9%97%AE%E9%A2%98/"/>
<url>/passages/20201018EGG%E5%AE%89%E5%85%A8%E9%97%AE%E9%A2%98/</url>
<content type="html"><![CDATA[<p><code>EGG</code> 安全问题配置</p><span id="more"></span><h2 id="Egg-https-配置"><a href="#Egg-https-配置" class="headerlink" title="Egg https 配置"></a>Egg https 配置</h2><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">config.<span class="property">cluster</span> = {</span><br><span class="line"> <span class="attr">listen</span>: {</span><br><span class="line"> <span class="attr">path</span>: <span class="string">""</span>,</span><br><span class="line"> <span class="attr">port</span>: <span class="number">443</span></span><br><span class="line"> },</span><br><span class="line"> <span class="attr">https</span>: {</span><br><span class="line"> <span class="attr">key</span>: key,</span><br><span class="line"> <span class="attr">cert</span>: cert,</span><br><span class="line"> <span class="attr">ciphers</span>: <span class="string">'ECDHE-RSA-AES128-GCM-SHA256'</span> <span class="comment">//此参数并不支持,需要修改源码lib包</span></span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p><code>node-modules/egg-cluster/lib/app_worker.js</code></p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">if</span> (httpsOptions.<span class="property">ciphers</span>) {</span><br><span class="line"> httpsOptions.<span class="property">ciphers</span> = httpsOptions.<span class="property">ciphers</span>;</span><br><span class="line">}</span><br><span class="line"></span><br></pre></td></tr></table></figure><h2 id="Egg-安全配置"><a href="#Egg-安全配置" class="headerlink" title="Egg 安全配置"></a>Egg 安全配置</h2><p><code>node-modules/egg-cluster/lib/app_worker.js</code></p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// SSL/TLS存在重协商漏洞</span></span><br><span class="line"><span class="keyword">var</span> tls = <span class="built_in">require</span>(<span class="string">'tls'</span>);</span><br><span class="line"></span><br><span class="line">tls.<span class="property">CLIENT_RENEG_LIMIT</span> = <span class="number">0</span>;</span><br><span class="line">tls.<span class="property">CLIENT_RENEG_WINDOW</span> = <span class="number">0</span>;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">// HTTPS慢速拒绝服务漏洞</span></span><br><span class="line">server.<span class="property">headersTimeout</span> = <span class="number">9</span> * <span class="number">1000</span>;</span><br><span class="line">server.<span class="property">maxHeadersCount</span> = <span class="number">2000</span>;</span><br></pre></td></tr></table></figure><p><code>静态资源添加响应头</code></p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// app/route.js</span></span><br><span class="line"><span class="keyword">const</span> initStatic = app.<span class="property">config</span>.<span class="property">coreMiddleware</span>.<span class="title function_">indexOf</span>(<span class="string">'static'</span>);</span><br><span class="line"><span class="keyword">const</span> uedStatic = app.<span class="property">middleware</span>.<span class="title function_">uedStatic</span>();</span><br><span class="line">app.<span class="property">middleware</span>.<span class="title function_">splice</span>(initStatic, <span class="number">0</span>, uedStatic);</span><br><span class="line"></span><br><span class="line"><span class="comment">// middleware/ued_static.js</span></span><br><span class="line"><span class="variable language_">module</span>.<span class="property">exports</span> = <span class="function">() =></span> {</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">async</span> <span class="keyword">function</span> <span class="title function_">uedStatic</span>(<span class="params">ctx, next</span>) {</span><br><span class="line"> <span class="keyword">if</span> (ctx.<span class="property">request</span>.<span class="property">url</span>.<span class="title function_">indexOf</span>(<span class="string">"/js/"</span>) || ctx.<span class="property">request</span>.<span class="property">url</span>.<span class="title function_">indexOf</span>(<span class="string">"/css/"</span> || ctx.<span class="property">request</span>.<span class="property">url</span>.<span class="title function_">indexOf</span>(<span class="string">"/img/"</span>))) {</span><br><span class="line"> ctx.<span class="property">response</span>.<span class="title function_">set</span>({</span><br><span class="line"> <span class="string">"响应头key"</span>: <span class="string">"响应头Value"</span></span><br><span class="line"> })</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">await</span> <span class="title function_">next</span>();</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br></pre></td></tr></table></figure><h2 id="参考"><a href="#参考" class="headerlink" title="参考"></a>参考</h2><ul><li><a href="https://github.com/eggjs/egg/issues/3523">EGG router static 捕获</a></li></ul>]]></content>
<categories>
<category> EGG </category>
</categories>
<tags>
<tag> EGG </tag>
<tag> HTTPS </tag>
<tag> 安全问题 </tag>
</tags>
</entry>
<entry>
<title>HTTPS 证书管理</title>
<link href="/passages/20200823%E8%AF%81%E4%B9%A6%E7%AE%A1%E7%90%86/"/>
<url>/passages/20200823%E8%AF%81%E4%B9%A6%E7%AE%A1%E7%90%86/</url>
<content type="html"><![CDATA[<p><code>HTTPS</code> 证书管理,自签名证书的生成,证书信息的获取,证书的上传验证,删除等</p><span id="more"></span><h2 id="自签名证书生成"><a href="#自签名证书生成" class="headerlink" title="自签名证书生成"></a>自签名证书生成</h2><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line">openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout self.key -out self.crt -subj /CN=*.abc.com</span><br><span class="line"></span><br><span class="line"><span class="comment"># 使用sha256算法</span></span><br><span class="line">-sha256</span><br><span class="line"><span class="comment"># 默认情况下,openssl req自动创建私钥时都要求加密并提示输入加密密码,指定该选项后则禁止对私钥文件加密</span></span><br><span class="line">-nodes</span><br><span class="line"><span class="comment"># 证书有效期365天</span></span><br><span class="line">-days 365</span><br><span class="line"><span class="comment"># 2048位密钥</span></span><br><span class="line">rsa:2048</span><br><span class="line"><span class="comment"># :密钥文件,自己命名</span></span><br><span class="line">self.key</span><br><span class="line"><span class="comment"># iphone、mac等使用的证书文件</span></span><br><span class="line">self.crt</span><br><span class="line"><span class="comment"># 使用abc.com域名的通配方式作为使用者</span></span><br><span class="line">-subj /CN=*.abc.com</span><br><span class="line"></span><br><span class="line"><span class="comment"># 生成windows使用的证书文件pfx, 执行后,会提示输入证书密码</span></span><br><span class="line">openssl pkcs12 -<span class="built_in">export</span> -out self.pfx -inkey self.key -<span class="keyword">in</span> self.crt</span><br></pre></td></tr></table></figure><h2 id="证书信息的获取"><a href="#证书信息的获取" class="headerlink" title="证书信息的获取"></a>证书信息的获取</h2><p>注意:本例初始化的证书存储位置与上传证书位置不一致,上传的证书只保留最新的一份。<br>每次服务启动时读取上传路径的,没有,则读取使用初始化的。<br>获取证书信息同理。</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> fs = <span class="built_in">require</span>(<span class="string">'fs'</span>);</span><br><span class="line"><span class="keyword">const</span> childProcess = <span class="built_in">require</span>(<span class="string">'child_process'</span>);</span><br><span class="line"><span class="keyword">const</span> path = <span class="built_in">require</span>(<span class="string">'path'</span>);</span><br><span class="line"><span class="keyword">const</span> uploadDir = <span class="string">"上传路径"</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> pem;</span><br><span class="line"><span class="keyword">if</span> (fs.<span class="title function_">existsSync</span>(path.<span class="title function_">join</span>(uploadDir, <span class="string">'cert.pem'</span>))) {</span><br><span class="line"> pem = path.<span class="title function_">join</span>(uploadDir, <span class="string">'cert.pem'</span>);</span><br><span class="line">} <span class="keyword">else</span> {</span><br><span class="line"> pem = <span class="string">'cert.pem'</span>; <span class="comment">//初始</span></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> cmdStr = <span class="string">`openssl x509 -in <span class="subst">${pem}</span> -noout -serial &&</span></span><br><span class="line"><span class="string"> opensll x509 -in <span class="subst">${pem}</span> -noout -subject && </span></span><br><span class="line"><span class="string"> opensll x509 -in <span class="subst">${pem}</span> -noout -issuer &&</span></span><br><span class="line"><span class="string"> opensll x509 -in <span class="subst">${pem}</span> -noout -startdate &&</span></span><br><span class="line"><span class="string"> opensll x509 -in <span class="subst">${pem}</span> -noout -enddate`</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">try</span> {</span><br><span class="line"> <span class="keyword">let</span> stdoutArray = childProcess.<span class="title function_">execSync</span>(cmdStr).<span class="title function_">toString</span>().<span class="title function_">split</span>(<span class="string">'\n'</span>);</span><br><span class="line"> <span class="keyword">let</span> data = {</span><br><span class="line"> <span class="attr">serial</span>: stdoutArray[<span class="number">0</span>].<span class="title function_">replace</span>(<span class="string">'serial='</span>, <span class="string">""</span>), <span class="comment">//序列号</span></span><br><span class="line"> <span class="attr">subject</span>: stdoutArray[<span class="number">1</span>].<span class="title function_">replace</span>(<span class="string">'subject='</span>, <span class="string">""</span>), <span class="comment">//颁发给</span></span><br><span class="line"> <span class="attr">issuer</span>: stdoutArray[<span class="number">2</span>].<span class="title function_">replace</span>(<span class="string">'issuer='</span>, <span class="string">""</span>), <span class="comment">//颁发者</span></span><br><span class="line"> <span class="attr">notBefore</span>: stdoutArray[<span class="number">3</span>].<span class="title function_">replace</span>(<span class="string">'notBefore='</span>, <span class="string">""</span>), <span class="comment">//开始时间</span></span><br><span class="line"> <span class="attr">notAfter</span>: stdoutArray[<span class="number">4</span>].<span class="title function_">replace</span>(<span class="string">'notAfter='</span>, <span class="string">""</span>), <span class="comment">//失效时间</span></span><br><span class="line"> }</span><br><span class="line">} <span class="keyword">catch</span>(err) {</span><br><span class="line"> <span class="variable language_">console</span>.<span class="title function_">log</span>(err);</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="证书的验证及上传存储"><a href="#证书的验证及上传存储" class="headerlink" title="证书的验证及上传存储"></a>证书的验证及上传存储</h2><p>本例前端使用表单提交,后端 Nodejs 接收。</p><p>前端使用 <code>Element UI</code> 的文件上传组件, 后端利用 eggjs 的 <code>egg-multipart</code> 插件,需要先配置扩展,支持对应格式 <code>pfx</code></p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">async</span> <span class="title function_">upload</span>(<span class="params"></span>) {</span><br><span class="line"> <span class="keyword">const</span> uploadDir = <span class="string">"上传路径"</span></span><br><span class="line"> <span class="keyword">const</span> stream = <span class="keyword">await</span> ctx.<span class="title function_">getFileStream</span>();</span><br><span class="line"> <span class="keyword">if</span> (!fs.<span class="title function_">existsSync</span>(uploadDir)) {</span><br><span class="line"> fs.<span class="title function_">mkdirSync</span>(uploadDir)</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">const</span> target = path.<span class="title function_">join</span>(uploadDir, <span class="string">"temp.pfx"</span>);</span><br><span class="line"> <span class="keyword">const</span> writeStream = fs.<span class="title function_">createWriteStream</span>(target);</span><br><span class="line"> stream.<span class="title function_">pipe</span>(writeStream);</span><br><span class="line"></span><br><span class="line"> <span class="keyword">let</span> password = stream.<span class="property">fields</span>.<span class="property">password</span>; <span class="comment">//form 参数 by `stream.fields`</span></span><br><span class="line"></span><br><span class="line"> <span class="keyword">let</span> pfx = path.<span class="title function_">join</span>(uploadDir, <span class="string">'temp.pfx'</span>);</span><br><span class="line"> <span class="keyword">let</span> pem = path.<span class="title function_">join</span>(uploadDir, <span class="string">'temp.pem'</span>);</span><br><span class="line"> <span class="keyword">let</span> key = path.<span class="title function_">join</span>(uploadDir, <span class="string">'temp-key.pem'</span>);</span><br><span class="line"> <span class="keyword">let</span> cert = path.<span class="title function_">join</span>(uploadDir, <span class="string">'temp-cert.pem'</span>);</span><br><span class="line"> </span><br><span class="line"> <span class="comment">// pfx && password 解析出 pem</span></span><br><span class="line"> <span class="comment">// 验证-可能存在 verify 验证证书报错</span></span><br><span class="line"> <span class="comment">// 转为 key && cert</span></span><br><span class="line"> <span class="keyword">let</span> cmdStr = <span class="string">`openssl pkcs12 -in <span class="subst">${pfx}</span> -nodes -out <span class="subst">${pem}</span> -password pass:<span class="subst">${password}</span> &&</span></span><br><span class="line"><span class="string"> openssl verify <span class="subst">${pem}</span> && </span></span><br><span class="line"><span class="string"> openssl rsa -in <span class="subst">${pem}</span> -out <span class="subst">${key}</span> &&</span></span><br><span class="line"><span class="string"> openssl x509 -in <span class="subst">${pem}</span> -out <span class="subst">${cert}</span>`</span>;</span><br><span class="line"></span><br><span class="line"> <span class="keyword">let</span> execPromise = <span class="keyword">new</span> <span class="title class_">Promise</span>(<span class="function">(<span class="params">resolve, reject</span>) =></span> {</span><br><span class="line"> childProcess.<span class="title function_">exec</span>(cmdStr, <span class="keyword">function</span>(<span class="params">error, stdout, stderr</span>) {</span><br><span class="line"> <span class="keyword">if</span> (error) {</span><br><span class="line"> <span class="keyword">return</span> <span class="title function_">resolve</span>({</span><br><span class="line"> <span class="attr">code</span>: <span class="number">1</span>,</span><br><span class="line"> <span class="attr">msg</span>: <span class="string">"Wrong certificate or password"</span></span><br><span class="line"> })</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> <span class="keyword">if</span> (stdout.<span class="title function_">indexof</span>(<span class="string">'certificate has expired'</span>) > -<span class="number">1</span>) {</span><br><span class="line"> <span class="keyword">return</span> <span class="title function_">resolve</span>({</span><br><span class="line"> <span class="attr">code</span>: <span class="number">2</span>,</span><br><span class="line"> <span class="attr">data</span>: <span class="string">"expired"</span>,</span><br><span class="line"> <span class="attr">msg</span>: stdout</span><br><span class="line"> })</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> <span class="keyword">return</span> <span class="title function_">resolve</span>({</span><br><span class="line"> <span class="attr">code</span>: <span class="number">0</span>,</span><br><span class="line"> <span class="attr">msg</span>: stdout</span><br><span class="line"> })</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> })</span><br><span class="line"> })</span><br><span class="line"> <span class="keyword">let</span> data = <span class="keyword">await</span> execPromise;</span><br><span class="line"> ctx.<span class="property">body</span> = data;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="证书上传后重启服务"><a href="#证书上传后重启服务" class="headerlink" title="证书上传后重启服务"></a>证书上传后重启服务</h2><p>证书上传后,将原来上传证书删除,然后新上传的重命名,保证服务重启后读取的证书为刚刚上传的。</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">async</span> <span class="title function_">restart</span>(<span class="params"></span>) {</span><br><span class="line"> <span class="comment">// 之前上传的先删除,然后把刚上传的重命名</span></span><br><span class="line"> <span class="keyword">let</span> key = path.<span class="title function_">join</span>(uploadDir, <span class="string">'key.pem'</span>);</span><br><span class="line"> <span class="keyword">let</span> cert = path.<span class="title function_">join</span>(uploadDir, <span class="string">'cert.pem'</span>);</span><br><span class="line"> <span class="keyword">if</span> (fs.<span class="title function_">existsSync</span>(key)) {</span><br><span class="line"> fs.<span class="title function_">unlinkSync</span>(key);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (fs.<span class="title function_">existsSync</span>(cert)) {</span><br><span class="line"> fs.<span class="title function_">unlinkSync</span>(cert);</span><br><span class="line"> }</span><br><span class="line"> <span class="comment">// 上步生成的</span></span><br><span class="line"> <span class="keyword">let</span> tempKey = path.<span class="title function_">join</span>(uploadDir, <span class="string">'temp-key.pem'</span>);</span><br><span class="line"> <span class="keyword">let</span> tempCert = path.<span class="title function_">join</span>(uploadDir, <span class="string">'temp-cert.pem'</span>);</span><br><span class="line"> <span class="keyword">try</span> {</span><br><span class="line"> fs.<span class="title function_">renameSync</span>(tempKey, key),</span><br><span class="line"> fs.<span class="title function_">renameSync</span>(tempCert, cert);</span><br><span class="line"> } <span class="keyword">catch</span> (e) {</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">let</span> cmdStr = <span class="string">`restart node`</span> <span class="comment">//重启服务命令</span></span><br><span class="line"> childProcess.<span class="title function_">exec</span>(<span class="params">cmdStr, <span class="keyword">function</span>(error, stdout, stderr)</span>) {</span><br><span class="line"> <span class="keyword">if</span>(error) {</span><br><span class="line"> ctx.<span class="property">logger</span>.<span class="title function_">error</span>(error)</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 服务重启,无法回调,直接返回</span></span><br><span class="line"> ctx.<span class="property">body</span> = {</span><br><span class="line"> <span class="attr">code</span>: <span class="number">0</span>,</span><br><span class="line"> <span class="attr">msg</span>: <span class="string">""</span></span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="证书文件的删除"><a href="#证书文件的删除" class="headerlink" title="证书文件的删除"></a>证书文件的删除</h2><p>用于上传后提示过期,选择不应用。或者上传后直接取消应用的场景</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">async</span> <span class="title function_">delete</span>(<span class="params"></span>) {</span><br><span class="line"> <span class="keyword">let</span> pfx = path.<span class="title function_">join</span>(uploadDir, <span class="string">'temp.pfx'</span>); </span><br><span class="line"> <span class="keyword">let</span> pem = path.<span class="title function_">join</span>(uploadDir, <span class="string">'temp.pem'</span>); </span><br><span class="line"> <span class="keyword">let</span> key = path.<span class="title function_">join</span>(uploadDir, <span class="string">'temp-key.pem'</span>); </span><br><span class="line"> <span class="keyword">let</span> cert = path.<span class="title function_">join</span>(uploadDir, <span class="string">'temp-cert.pem'</span>); </span><br><span class="line"> <span class="keyword">if</span> (fs.<span class="title function_">existsSync</span>(pfx)) {</span><br><span class="line"> fs.<span class="title function_">unlinkSync</span>(pfx);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (fs.<span class="title function_">existsSync</span>(pem)) {</span><br><span class="line"> fs.<span class="title function_">unlinkSync</span>(pem);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (fs.<span class="title function_">existsSync</span>(key)) {</span><br><span class="line"> fs.<span class="title function_">unlinkSync</span>(key);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (fs.<span class="title function_">existsSync</span>(cert)) {</span><br><span class="line"> fs.<span class="title function_">unlinkSync</span>(cert);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> ctx.<span class="property">body</span> = {</span><br><span class="line"> <span class="attr">code</span>: <span class="number">0</span>,</span><br><span class="line"> <span class="attr">msg</span>: <span class="string">""</span></span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="Egg-https-配置"><a href="#Egg-https-配置" class="headerlink" title="Egg https 配置"></a>Egg https 配置</h2><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">config.<span class="property">cluster</span> = {</span><br><span class="line"> <span class="attr">listen</span>: {</span><br><span class="line"> <span class="attr">path</span>: <span class="string">""</span>,</span><br><span class="line"> <span class="attr">port</span>: <span class="number">443</span></span><br><span class="line"> },</span><br><span class="line"> <span class="attr">https</span>: {</span><br><span class="line"> <span class="attr">key</span>: key,</span><br><span class="line"> <span class="attr">cert</span>: cert,</span><br><span class="line"> <span class="attr">ciphers</span>: <span class="string">'ECDHE-RSA-AES128-GCM-SHA256'</span> <span class="comment">//此参数并不支持,需要修改源码lib包</span></span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p><code>node-modules/egg-cluster/lib/app_worker.js</code></p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">if</span> (httpsOptions.<span class="property">ciphers</span>) {</span><br><span class="line"> httpsOptions.<span class="property">ciphers</span> = httpsOptions.<span class="property">ciphers</span>;</span><br><span class="line">}</span><br><span class="line"></span><br></pre></td></tr></table></figure><h2 id="参考"><a href="#参考" class="headerlink" title="参考"></a>参考</h2><ul><li><a href="https://www.openssl.org/">OpenSSL 官网</a></li><li><a href="http://nodejs.cn/api/https.html">Nodejs HTTPS</a></li><li><a href="http://nodejs.cn/api/tls.html">Nodejs TLS</a></li><li><a href="http://nodejs.cn/api/child_process.html">Nodejs child_process</a></li><li><a href="http://nodejs.cn/api/fs.html">Nodejs fs</a></li><li><a href="https://blog.csdn.net/wuwo333/article/details/53020403">OpenSSL 生成自签名证书</a></li><li><a href="https://www.cnblogs.com/shenlinken/p/9968274.html">OpenSSL 查看证书细节</a></li><li><a href="https://www.cnblogs.com/aixiaoxiaoyu/p/8650180.html">OpenSSL 命令目录</a></li><li><a href="https://blog.csdn.net/as3luyuan123/article/details/16872101">OpenSSL verify</a></li><li><a href="https://blog.csdn.net/u010358168/article/details/83508851">OpenSSL 证书格式转换</a></li><li><a href="https://wiki.jikexueyuan.com/project/nodejs/tls.html">TLS/SSL</a></li><li><a href="https://www.ctolib.com/docs-nodejs-learn-c-a18q1iu5.html#tls_class_tls_tlssocket">TLS/SSL</a></li></ul>]]></content>
<categories>
<category> 工程部署 </category>
</categories>
<tags>
<tag> 证书管理 </tag>
<tag> HTTPS </tag>
</tags>
</entry>
<entry>
<title>JavaScript 屏幕可视元素</title>
<link href="/passages/20200814%E5%B1%8F%E5%B9%95%E5%8F%AF%E8%A7%86%E5%85%83%E7%B4%A0/"/>
<url>/passages/20200814%E5%B1%8F%E5%B9%95%E5%8F%AF%E8%A7%86%E5%85%83%E7%B4%A0/</url>
<content type="html"><![CDATA[<p><code>JavaScript</code> 屏幕可视</p><span id="more"></span><h2 id="需求描述"><a href="#需求描述" class="headerlink" title="需求描述"></a>需求描述</h2><p>日常开发中, 遇到元素特别多的页面, 例如全是图表的页面,如果图表过多,造成页面卡顿。<br>若<code>只显示在屏幕可视范围内的图</code>,范围外的<code>销毁</code>,可大大提高页面性能。</p><h2 id="具体实现"><a href="#具体实现" class="headerlink" title="具体实现"></a>具体实现</h2><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">isOnScreen</span>(<span class="params">element</span>) {</span><br><span class="line"> <span class="keyword">let</span> on_screen_height = <span class="number">20</span>; <span class="comment">// 偏移量</span></span><br><span class="line"></span><br><span class="line"> <span class="keyword">let</span> rect = element.<span class="title function_">getBoundingClientRect</span>();</span><br><span class="line"> <span class="keyword">let</span> windowHeight = <span class="variable language_">window</span>.<span class="property">innerHeight</span> || <span class="variable language_">document</span>.<span class="property">documentElement</span>.<span class="property">clientHeight</span>;</span><br><span class="line"></span><br><span class="line"> <span class="keyword">let</span> elementHeight = element.<span class="property">offsetHeight</span>;</span><br><span class="line"></span><br><span class="line"> <span class="keyword">let</span> onScreenHeight = on_screen_height > elementHeight ?</span><br><span class="line"> elementHeight : on_screen_height;</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 元素在屏幕上方, 如果元素不是从屏幕最上侧开始的,需要减去对应值(rect.top 不是 0)</span></span><br><span class="line"> <span class="keyword">let</span> elementBottomToWindowTop = rect.<span class="property">top</span> + elementHeight;</span><br><span class="line"> <span class="keyword">let</span> bottomBoundingOnScreen = elementBottomToWindowTop >= onScreenHeight;</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 元素在屏幕下方</span></span><br><span class="line"> <span class="keyword">let</span> elementTopToWindowBottom = windowHeight - (rect.<span class="property">bottom</span> - elementHeight);</span><br><span class="line"> <span class="keyword">let</span> topBoundingOnScreen = elementTopToWindowBottom >= onScreenHeight;</span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> bottomBoundingOnScreen && topBoundingOnScreen;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">let</span> i=<span class="number">0</span>; i<=<span class="number">6</span>; i++) {</span><br><span class="line"> <span class="keyword">let</span> element = <span class="variable language_">document</span>.<span class="title function_">getElementById</span>(i);</span><br><span class="line"> <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title function_">isOnScreen</span>(element))</span><br><span class="line"> <span class="keyword">if</span> (<span class="title function_">isOnScreen</span>(element)) {</span><br><span class="line"> <span class="keyword">if</span> () { <span class="comment">//没数据</span></span><br><span class="line"> <span class="comment">// 获取对应数据</span></span><br><span class="line"> }</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> <span class="comment">// 销毁</span></span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br></pre></td></tr></table></figure><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag"><<span class="name">ul</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">li</span> <span class="attr">id</span>=<span class="string">"0"</span>></span><span class="tag"></<span class="name">li</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">li</span> <span class="attr">id</span>=<span class="string">"1"</span>></span><span class="tag"></<span class="name">li</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">li</span> <span class="attr">id</span>=<span class="string">"2"</span>></span><span class="tag"></<span class="name">li</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">li</span> <span class="attr">id</span>=<span class="string">"3"</span>></span><span class="tag"></<span class="name">li</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">li</span> <span class="attr">id</span>=<span class="string">"4"</span>></span><span class="tag"></<span class="name">li</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">li</span> <span class="attr">id</span>=<span class="string">"5"</span>></span><span class="tag"></<span class="name">li</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">li</span> <span class="attr">id</span>=<span class="string">"6"</span>></span><span class="tag"></<span class="name">li</span>></span></span><br><span class="line"> ...</span><br><span class="line"><span class="tag"></<span class="name">ul</span>></span></span><br></pre></td></tr></table></figure><h2 id="滚动结束事件"><a href="#滚动结束事件" class="headerlink" title="滚动结束事件"></a>滚动结束事件</h2><p>由于原生 JavaScript 没有对应滑动结束事件,需要采取定时模拟</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> element = <span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">'id'</span>);</span><br><span class="line"></span><br><span class="line">element.<span class="property">onscroll</span> = <span class="function">() =></span> {</span><br><span class="line"> <span class="keyword">if</span> (<span class="variable language_">window</span>.<span class="property">scrollTimer</span>) {</span><br><span class="line"> <span class="built_in">clearTimeout</span>(<span class="variable language_">window</span>.<span class="property">scrollTimer</span>) <span class="comment">// 普通写法</span></span><br><span class="line"> <span class="comment">// vue写法,由于vue对setTimeout修改,则需要id,否则无法清除</span></span><br><span class="line"> <span class="built_in">clearTimeout</span>(<span class="variable language_">window</span>.<span class="property">scrollTimer</span>.<span class="property">_id</span>)</span><br><span class="line"> }</span><br><span class="line"> <span class="variable language_">window</span>.<span class="property">scrollTimer</span> = <span class="built_in">setTimeout</span>(callback, <span class="number">300</span>)</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">callback</span>(<span class="params"></span>) {</span><br><span class="line"> <span class="comment">// 执行滑动结束后内容</span></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// 平滑过渡</span></span><br><span class="line">element.<span class="title function_">scrollTo</span>({</span><br><span class="line"> <span class="attr">left</span>: <span class="number">0</span>,</span><br><span class="line"> <span class="attr">top</span>: num,</span><br><span class="line"> <span class="attr">behavior</span>: <span class="string">'smooth'</span></span><br><span class="line">})</span><br></pre></td></tr></table></figure>]]></content>
<categories>
<category> JavaScript </category>
</categories>
<tags>
<tag> 屏幕可视 </tag>
</tags>
</entry>
<entry>
<title>JavaScript 原型与原型链</title>
<link href="/passages/20200807%E5%8E%9F%E5%9E%8B%E4%B8%8E%E5%8E%9F%E5%9E%8B%E9%93%BE/"/>
<url>/passages/20200807%E5%8E%9F%E5%9E%8B%E4%B8%8E%E5%8E%9F%E5%9E%8B%E9%93%BE/</url>
<content type="html"><![CDATA[<p><code>JavaScript</code> 原型与原型链</p><span id="more"></span><h2 id="基本概念"><a href="#基本概念" class="headerlink" title="基本概念"></a>基本概念</h2><blockquote><p>每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,而实例都包含一个指向原型对象的内部指针。那么,假如我们让原型对象等于另一个类型的实例,结果会怎么样呢?显然,此时的原型对象将包含一个指向另一个原型的指针,相应地,另一个原型中也包含着一个指向另一个构造函数的指针。假如另一个原型又是另一个类型的实例,那么上述关系依然成立,如此层层递进,就构成了实例与原型的链条。这就是所谓原型链的基本概念</p></blockquote><ul><li>构造函数 <code>Person</code></li><li>原型对象 <code>Person.prototype</code></li><li>原型对象都包含一个指向构造函数的指针 <code>constructor</code></li><li>实例都包含一个指向原型对象的内部指针 <code>person --- __proto__ > Person.prototype</code></li><li>结果:<code>Person.prototype</code> === <code>obejct</code> ?<br> => 由上推出条件一:<code>Person.prototype.__proto__ == obejct.__proto__</code> ,条件二:<code>object.__proto__ == Object.prototype</code></li><li>从而推出 <code>Person.prototype.__proto__ === Object.prototype</code></li></ul><p>每一个对象都有 <code>__proto__</code> 属性, 指向对应的构造函数的 <code>prototype</code> 属性.</p><p><code>class</code> 为构造函数的语法糖, 数据类型是函数,类本身就指向构造函数。</p><p><img src="/images/post/原型链.png" alt=""></p><p>图中由相互关联的原型 <code>(__proto__)</code> 组成的链状结构就是原型链,也就是由 <code>__proto__</code> 连接的这条线.</p><h2 id="类的实例对象"><a href="#类的实例对象" class="headerlink" title="类的实例对象"></a>类的实例对象</h2><p>类的所有实例共享一个原型对象.</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Point</span> {</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> p1 = <span class="keyword">new</span> <span class="title class_">Point</span>();</span><br><span class="line"><span class="keyword">let</span> p2 = <span class="keyword">new</span> <span class="title class_">Point</span>();</span><br><span class="line"></span><br><span class="line">p1.<span class="property">__proto__</span> === p2.<span class="property">__proto__</span> <span class="comment">// true</span></span><br><span class="line">p1.<span class="property">__proto__</span> === p2.<span class="property">__proto__</span> == <span class="title class_">Point</span>.<span class="property"><span class="keyword">prototype</span></span> <span class="comment">//true</span></span><br><span class="line"><span class="title class_">Point</span>.<span class="property">__proto__</span> === <span class="title class_">Function</span>.<span class="property"><span class="keyword">prototype</span></span> <span class="comment">// true</span></span><br></pre></td></tr></table></figure><p><code>p1 p2</code> 都为 Point 的实例,它们的原型 <code>(p1.__proto__, p2.__proto__)</code> 都等于 <code>Point.prototype</code>.</p><p>可以通过实例的 <code>__proto__</code> 给类添加方法,且所有共享.</p><h2 id="类的继承"><a href="#类的继承" class="headerlink" title="类的继承"></a>类的继承</h2><p><code>class</code> 为构造函数的语法糖. 同时有 <code>prototype</code> 和 <code>__proto__</code> 属性. 则存在两条继承链.</p><ul><li>子类的 <code>__proto__</code> 属性表示构造函数的继承,总是指向父类.</li><li>子类 <code>prototype</code> 属性的 <code>__proto__</code> 属性表示方法的继承,总是指向父类的 <code>prototype</code> 属性</li></ul><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Animal</span> {</span><br><span class="line"></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Dog</span> <span class="keyword">extends</span> <span class="title class_ inherited__">Animal</span> {</span><br><span class="line"></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="title class_">Dog</span>.<span class="property">__proto__</span> === <span class="title class_">Animal</span> <span class="comment">// true</span></span><br><span class="line"><span class="title class_">Dog</span>.<span class="property"><span class="keyword">prototype</span></span>.<span class="property">__proto__</span> === <span class="title class_">Animal</span>.<span class="property"><span class="keyword">prototype</span></span> <span class="comment">// true</span></span><br></pre></td></tr></table></figure><ul><li>作为对象,子类(Dog)的 <code>__proto__</code> 属性是父类(Animal)</li><li>作为构造函数,子类(Dog)的 <code>prototype</code> 属性的 <code>__proto__</code> 属性是父类的 <code>prototype</code> 属性</li></ul><h2 id="参考"><a href="#参考" class="headerlink" title="参考"></a>参考</h2><ul><li><a href="https://www.cnblogs.com/loveyaxin/p/11151586.html">javascript——原型与原型链</a></li><li><a href="https://www.cnblogs.com/weiyalin/p/9417361.html">JavaScript 原型链学习(四)原型链的基本概念、原型链实现继承</a></li></ul>]]></content>
<categories>
<category> JavaScript </category>
</categories>
<tags>
<tag> 原型与原型链 </tag>
</tags>
</entry>
<entry>
<title>EGG 日志梳理</title>
<link href="/passages/20200510EGG%E6%97%A5%E5%BF%97/"/>
<url>/passages/20200510EGG%E6%97%A5%E5%BF%97/</url>
<content type="html"><![CDATA[<p><code>EGG</code> 日志梳理</p><span id="more"></span><h2 id="EGG-启动"><a href="#EGG-启动" class="headerlink" title="EGG 启动"></a>EGG 启动</h2><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 本地</span></span><br><span class="line">npm run dev</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">// 生产环境</span></span><br><span class="line">npm run stop</span><br><span class="line">npm run start (--daemon <span class="comment">//后台启动)</span></span><br></pre></td></tr></table></figure><h2 id="EGG-生产环境日志"><a href="#EGG-生产环境日志" class="headerlink" title="EGG 生产环境日志"></a>EGG 生产环境日志</h2><h3 id="启动日志"><a href="#启动日志" class="headerlink" title="启动日志"></a>启动日志</h3><p>默认在 <code>${appInfo.root}/logs/</code></p><p><code>master-stderr.log</code><br><code>master-stdout.log</code></p><p>如果修改路径在 <code>package.json</code> 加参数</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">--stdout=<span class="regexp">/opt/</span>node/logs/master-stdout.<span class="property">log</span></span><br><span class="line">--stderr=<span class="regexp">/opt/</span>node/logs/master-stderr.<span class="property">log</span></span><br></pre></td></tr></table></figure><h3 id="定时任务日志"><a href="#定时任务日志" class="headerlink" title="定时任务日志"></a>定时任务日志</h3><p>默认在 <code>${appInfo.root}/logs/${appInfo.name}</code></p><p><code>egg-schedule.log</code></p><p>如果修改路径在 <code>config.prod.js</code></p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">config.<span class="property">logger</span> = {</span><br><span class="line"> <span class="attr">dir</span>: path.<span class="title function_">join</span>(<span class="string">'/opt/node/logs/'</span>, appInfo.<span class="property">name</span>)</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h3 id="业务日志"><a href="#业务日志" class="headerlink" title="业务日志"></a>业务日志</h3><p>默认在 <code>${appInfo.root}/logs/${appInfo.name}</code></p><p><code>common-error.log</code><br><code>egg-agent.log</code><br><code>egg-web.log</code><br><code>${appInfo.name}-web.log</code></p><p>如果修改路径在 <code>config.prod.js</code></p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">config.<span class="property">logger</span> = {</span><br><span class="line"> <span class="attr">dir</span>: path.<span class="title function_">join</span>(<span class="string">'/opt/node/logs/'</span>, appInfo.<span class="property">name</span>)</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h3 id="访问日志"><a href="#访问日志" class="headerlink" title="访问日志"></a>访问日志</h3><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//方式一-router.js</span></span><br><span class="line"><span class="keyword">const</span> requestRecord = app.<span class="property">middleware</span>.<span class="title function_">requestRecord</span>();</span><br><span class="line">router.<span class="title function_">all</span>(<span class="string">`<span class="subst">${ROOT_URL}</span>*`</span>, requestRecord);</span><br><span class="line"><span class="comment">//方式二-config.js</span></span><br><span class="line">config.<span class="property">middleware</span> = [<span class="string">'requestRecord'</span>];</span><br></pre></td></tr></table></figure><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// app/middleware/request_record.js</span></span><br><span class="line"><span class="variable language_">module</span>.<span class="property">exports</span> = <span class="function">(<span class="params">options, app</span>) =></span> {</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">async</span> <span class="keyword">function</span> <span class="title function_">requestRecord</span>(<span class="params">ctx, next</span>) {</span><br><span class="line"> ctx.<span class="property">logger</span>.<span class="title function_">info</span>(<span class="string">"httpVersion: %i referer: %j user-agent:"</span>, ctx.<span class="property">req</span>.<span class="property">httpVersion</span>, ctx.<span class="property">req</span>.<span class="property">headers</span>.<span class="property">referer</span>, ctx.<span class="property">req</span>.<span class="property">headers</span>[<span class="string">'user-agent'</span>]);</span><br><span class="line"> <span class="keyword">await</span> <span class="title function_">next</span>()</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="EGG-生产环境日志策略路径说明"><a href="#EGG-生产环境日志策略路径说明" class="headerlink" title="EGG 生产环境日志策略路径说明"></a>EGG 生产环境日志策略路径说明</h2><h3 id="分片策略"><a href="#分片策略" class="headerlink" title="分片策略"></a>分片策略</h3><ul><li>按天分割,且默认保存一个月(31天)</li></ul><h3 id="启动日志路径"><a href="#启动日志路径" class="headerlink" title="启动日志路径"></a>启动日志路径</h3><ul><li>/opt/node/logs/master-stdout.log</li><li>/opt/node/logs/master-stderr.log</li></ul><h3 id="定时任务日志路径"><a href="#定时任务日志路径" class="headerlink" title="定时任务日志路径"></a>定时任务日志路径</h3><ul><li>/opt/node/logs/server-egg/egg-schedule.log</li></ul><h3 id="业务日志路径"><a href="#业务日志路径" class="headerlink" title="业务日志路径"></a>业务日志路径</h3><ul><li>错误日志(errorLogger): /opt/node/logs/server-egg/common-error.log</li><li>应用相关日志,访问日志(appLogger): /opt/node/logs/server-egg/server-egg-web.log</li><li>框架内核、插件日志(coreLogger): /opt/node/logs/server-egg/egg-web.log</li><li>agent进程日志(agentLogger): /opt/node/logs/server-egg/egg-agent.log</li></ul><h3 id="注意"><a href="#注意" class="headerlink" title="注意"></a>注意</h3><ul><li>默认错误日志都会转到错误日志。</li></ul>]]></content>
<categories>
<category> EGG </category>
</categories>
<tags>
<tag> EGG </tag>
<tag> 日志 </tag>
</tags>
</entry>
<entry>
<title>从零搭建 Spring boot 工程</title>
<link href="/passages/20190902%E4%BB%8E0%E6%90%AD%E5%BB%BAspringboot%E5%B7%A5%E7%A8%8B/"/>
<url>/passages/20190902%E4%BB%8E0%E6%90%AD%E5%BB%BAspringboot%E5%B7%A5%E7%A8%8B/</url>
<content type="html"><![CDATA[<p>从零搭建 Spring boot 工程, 小白搭建后端工程记录。</p><span id="more"></span><h2 id="环境配置"><a href="#环境配置" class="headerlink" title="环境配置"></a>环境配置</h2><h3 id="JDK-安装配置"><a href="#JDK-安装配置" class="headerlink" title="JDK 安装配置"></a>JDK 安装配置</h3><ol><li>首先下载 <a href="https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html">jdk 1.8</a>,官网下载可能需要注册登录。</li><li>环境变量的配置,安装时按照默认路径安装完之后,环境变量自动配置完成。</li><li>启动控制台,<code>java -version</code> 看到版本说明安装成功。</li></ol><h3 id="maven-安装配置"><a href="#maven-安装配置" class="headerlink" title="maven 安装配置"></a>maven 安装配置</h3><ol><li>下载 <a href="https://maven.apache.org/download.cgi">maven</a>, <code>zip</code> 格式即可, 解压。</li><li>环境变量配置, 新建环境变量 变量名:<code>MAVEN_HOME</code>, 变量值:<code>E:\maven\apache-maven-3.6.1</code>.</li><li>修改 <code>PATH</code> 增加 <code>Maven</code> 路径。 <code>%MAVEN_HOME%\bin</code>.</li><li><code>mvn -v</code> 验证, 安装成功。</li><li>镜像库的更换与否,可以替换为阿里镜像库,或许会更快。</li></ol><p>若需要更换镜像库,修改 <code>settings.xml</code>即可,以下为阿里maven库配置。</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag"><<span class="name">mirror</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">id</span>></span>alimaven<span class="tag"></<span class="name">id</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">name</span>></span>aliyun maven<span class="tag"></<span class="name">name</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">url</span>></span>http://maven.aliyun.com/nexus/content/groups/public/<span class="tag"></<span class="name">url</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">mirrorOf</span>></span>central<span class="tag"></<span class="name">mirrorOf</span>></span></span><br><span class="line"><span class="tag"></<span class="name">mirror</span>></span></span><br></pre></td></tr></table></figure><h3 id="IntelliJ-IDEA-下载安装"><a href="#IntelliJ-IDEA-下载安装" class="headerlink" title="IntelliJ IDEA 下载安装"></a>IntelliJ IDEA 下载安装</h3><ol><li>下载安装 <a href="https://www.jetbrains.com/idea/download/#section=windows">IntelliJ IDEA</a></li><li>专业版的需要激活,试用30天.</li><li>按照提示直接安装即可.</li></ol><h2 id="新建工程"><a href="#新建工程" class="headerlink" title="新建工程"></a>新建工程</h2><h3 id="工程初始化"><a href="#工程初始化" class="headerlink" title="工程初始化"></a>工程初始化</h3><ol><li><code>New Project</code> -> <code>Spring Initializr</code> -> <code>Next</code>.</li><li><code>Group</code> 及 <code>artifact</code> 按照自己需要修改,对应 <code>package</code> 变化,-> <code>Next</code></li><li>选择 <code>Web</code> -> <code>Spring Web starter</code> -> <code>Next</code>.</li><li>选择 路径及文件夹,确定即可,等待工程初始化完成.</li><li>初始化下载依赖过程比较慢,提到上步 <code>Maven</code> 配置,可以改成阿里的。</li></ol><h3 id="工程配置"><a href="#工程配置" class="headerlink" title="工程配置"></a>工程配置</h3><ol><li><code>pom</code> 文件学习</li></ol><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag"><<span class="name">parent</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">groupId</span>></span>org.springframework.boot<span class="tag"></<span class="name">groupId</span>></span></span><br><span class="line"> <span class="comment"><!-- 这个依赖包含了应用运行需要的所有信息,它包含了Spring Boot应用所必须的类似于Spring FrameWork(spring-core)</span></span><br><span class="line"><span class="comment"> Spring Test(spring-test)等基础依赖的依赖描述。你只需要使用这个parent pom就能完成所有的依赖描述添加工作--></span></span><br><span class="line"> <span class="tag"><<span class="name">artifactId</span>></span>spring-boot-starter-parent<span class="tag"></<span class="name">artifactId</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">version</span>></span>2.1.7.RELEASE<span class="tag"></<span class="name">version</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">relativePath</span>/></span> <span class="comment"><!-- lookup parent from repository --></span></span><br><span class="line"><span class="tag"></<span class="name">parent</span>></span></span><br><span class="line"></span><br><span class="line"><span class="tag"><<span class="name">dependency</span>></span></span><br><span class="line"> <span class="comment"><!-- 添加这个依赖之后就可以创建一个web应用程序。starter poms部分可以引入所有需要在实际项目中使用的依赖。</span></span><br><span class="line"><span class="comment"> spring-boot-starter-web依赖包含所有的spring-core, spring-web, spring-webmvc,嵌入的Tomcat server和其他web应用相关的库。 --></span></span><br><span class="line"> <span class="tag"><<span class="name">groupId</span>></span>org.springframework.boot<span class="tag"></<span class="name">groupId</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">artifactId</span>></span>spring-boot-starter-web<span class="tag"></<span class="name">artifactId</span>></span></span><br><span class="line"><span class="tag"></<span class="name">dependency</span>></span></span><br></pre></td></tr></table></figure><ol start="2"><li>工程运行</li></ol><p>点击 <code>运行图标</code> 或者进入 项目根目录 <code>mvn spring-boot:run</code></p><ul><li>点击运行图标,启动正常。</li><li>项目个目录执行命令,可能会报 <code>No compiler is provided in this environment. Perhaps you are running on a JRE rather than a JDK?</code>, 环境问题.</li></ul><p>如果遇到上述,查看设置,file->settings->build->maven 配置是否正确,及参考以下方式解决。</p><ul><li><a href="https://blog.csdn.net/javajxz008/article/details/82791138">No compiler is provided in this environment</a></li></ul><ol start="3"><li>热加载</li></ol><p>新增如下依赖,热部署,但是设置完并未生效,修改ide配置, 验证成功.</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag"><<span class="name">dependency</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">groupId</span>></span>org.springframework.boot<span class="tag"></<span class="name">groupId</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">artifactId</span>></span>spring-boot-devtools<span class="tag"></<span class="name">artifactId</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">optional</span>></span>true<span class="tag"></<span class="name">optional</span>></span> <span class="comment"><!-- 这个需要为 true 热部署才有效 --></span></span><br><span class="line"><span class="tag"></<span class="name">dependency</span>></span></span><br></pre></td></tr></table></figure><ul><li><a href="https://blog.csdn.net/qq_34491508/article/details/83830075">Spring-boot-devTools无效解决办法,idea中devtools不起作用</a></li></ul><h2 id="运行"><a href="#运行" class="headerlink" title="运行"></a>运行</h2><p>运行正常,后续开发.</p><h2 id="参考"><a href="#参考" class="headerlink" title="参考"></a>参考</h2><ul><li><a href="https://www.cnblogs.com/tufujie/p/8950169.html">IDEA创建Spring Boot项目</a></li><li><a href="http://www.imooc.com/article/74491">使用IDEA创建spring boot项目与项目解析</a></li></ul>]]></content>
<categories>
<category> Spring </category>
</categories>
<tags>
<tag> Spring </tag>
<tag> 工程搭建 </tag>
</tags>
</entry>
<entry>
<title>Spring 相关常识</title>
<link href="/passages/20190826Spring%E5%B8%B8%E8%AF%86/"/>
<url>/passages/20190826Spring%E5%B8%B8%E8%AF%86/</url>
<content type="html"><![CDATA[<p>关于 spring 的一些常识</p><span id="more"></span><h2 id="spring"><a href="#spring" class="headerlink" title="spring"></a>spring</h2><p><code>Spring</code> 是一个轻量级控制反转(IoC)和面向切面(AOP)的容器框架。</p><h2 id="spring-mvc"><a href="#spring-mvc" class="headerlink" title="spring mvc"></a>spring mvc</h2><p><code>springMvc</code> 是 spring 基础之上的一个 MVC 框架, Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块.<br>主要处理 web 开发的路径映射和视图渲染,属于 spring 框架中 WEB 层开发的一部分.</p><h2 id="ssm"><a href="#ssm" class="headerlink" title="ssm"></a>ssm</h2><p><code>SSM(Spring + SpringMVC + MyBatis)</code> 框架集由 Spring、MyBatis 两个开源框架整合而成(SpringMVC是Spring中的部分内容).</p><h2 id="spring-boot"><a href="#spring-boot" class="headerlink" title="spring boot"></a>spring boot</h2><p><code>Spring Boot</code> 就是一些库的集合, 默认优于配置,简化了插件配置流程,不需要配置xml. 不仅继承了 Spring 框架原有的优秀特性,而且还通过简化配置来进一步简化了 Spring 应用的整个搭建和开发过程。另外 SpringBoot 通过集成大量的框架使得依赖包的版本冲突,以及引用的不稳定性等问题得到了很好的解决</p><h2 id="spring-cloud"><a href="#spring-cloud" class="headerlink" title="spring cloud"></a>spring cloud</h2><p><code>Spring Cloud</code> 是一系列框架的有序集合, 利用 Spring Boot 的开发便利性巧妙地简化了分布式系统基础设施的开发. <code>Spring Cloud</code> 关注于全局的微服务整合和管理,将多个 Spring Boot单体微服务进行整合以及管理, SpringCloud 依赖于 SpringBoot 开发,而 SpringBoot 可以独立开发;</p>]]></content>
<categories>
<category> Spring </category>
</categories>
<tags>
<tag> Spring </tag>
</tags>
</entry>
<entry>
<title>JavaScript 实现版权信息固定在页面底部</title>
<link href="/passages/20190710%E7%89%88%E6%9D%83%E5%9B%BA%E5%AE%9A%E5%BA%95%E9%83%A8/"/>
<url>/passages/20190710%E7%89%88%E6%9D%83%E5%9B%BA%E5%AE%9A%E5%BA%95%E9%83%A8/</url>
<content type="html"><![CDATA[<p>日常工作中,关于版权的布局,要一直在页面底部,需要处理屏幕高度和网页真实高度的关系。</p><span id="more"></span><h2 id="问题描述"><a href="#问题描述" class="headerlink" title="问题描述"></a>问题描述</h2><ol><li>若采用 <code>fixed</code> 定位,则可以保持版权一直在底部。(适用于屏幕高度 > 网页真实高度)</li><li>采用正常文档流,版权出现在网页底部。(适用于屏幕高度 < 网页真实高度)。否则会漂上去。</li></ol><h2 id="CSS-定位"><a href="#CSS-定位" class="headerlink" title="CSS 定位"></a>CSS 定位</h2><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="selector-class">.layout-copy2</span> {</span><br><span class="line"> <span class="attribute">position</span>: fixed;</span><br><span class="line"> <span class="attribute">bottom</span>: <span class="number">30px</span>;</span><br><span class="line"> <span class="attribute">left</span>: <span class="number">50%</span>;</span><br><span class="line"> <span class="attribute">transform</span>: <span class="built_in">translateX</span>(-<span class="number">50%</span>);</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="JavaScript-处理兼容"><a href="#JavaScript-处理兼容" class="headerlink" title="JavaScript 处理兼容"></a>JavaScript 处理兼容</h2><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">copyrightAuto</span>(<span class="params"></span>) {</span><br><span class="line"> <span class="keyword">let</span> winHeight = <span class="variable language_">document</span>.<span class="property">body</span>.<span class="property">clientHeight</span>; <span class="comment">//窗口高度</span></span><br><span class="line"> <span class="keyword">let</span> bodyHeight = <span class="variable language_">document</span>.<span class="title function_">getElementsByTagName</span>(<span class="string">'body'</span>)[<span class="number">0</span>].<span class="property">clientHeight</span> <span class="comment">//网页高度</span></span><br><span class="line"> <span class="keyword">if</span> (winHeight > bodyHeight) { <span class="comment">//窗口 > 网页</span></span><br><span class="line"> <span class="variable language_">document</span>.<span class="title function_">getElementsByClassName</span>(<span class="string">'layout-copy'</span>)[<span class="number">0</span>].<span class="property">classList</span>.<span class="title function_">add</span>(<span class="string">'layout-copy2'</span>);</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> <span class="variable language_">document</span>.<span class="title function_">getElementsByClassName</span>(<span class="string">'layout-copy'</span>)[<span class="number">0</span>].<span class="property">classList</span>.<span class="title function_">remove</span>(<span class="string">'layout-copy2'</span>);</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="调用"><a href="#调用" class="headerlink" title="调用"></a>调用</h2><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="title function_">copyrightAuto</span>();</span><br><span class="line"><span class="variable language_">window</span>.<span class="property">onresize</span> = <span class="keyword">function</span>(<span class="params"></span>) { <span class="comment">//监控窗口变化</span></span><br><span class="line"> <span class="title function_">copyrightAuto</span>();</span><br><span class="line">}</span><br></pre></td></tr></table></figure>]]></content>
<categories>
<category> JavaScript </category>
</categories>
<tags>
<tag> 版权固定 </tag>
</tags>
</entry>
<entry>
<title>CSS Grid 布局</title>
<link href="/passages/20190608Grid%E5%B8%83%E5%B1%80/"/>
<url>/passages/20190608Grid%E5%B8%83%E5%B1%80/</url>
<content type="html"><![CDATA[<p>CSS <code>网格布局(Grid)</code> 布局,学习练习。</p><span id="more"></span><h2 id="关于-Grid"><a href="#关于-Grid" class="headerlink" title="关于 Grid"></a>关于 Grid</h2><p><code>CSS Grid</code> 布局是 CSS 中最强大的布局系统。与 flexbox 的一维布局系统不同,<code>CSS Grid</code> 布局是一个 <code>二维布局系统</code>,也就意味着它可以同时处理列和行。通过将 CSS 规则应用于 父元素 (成为 <code>Grid Container 网格容器</code>)和其子元素(成为 <code>Grid Items 网格项</code>),你就可以轻松使用 <code>Grid(网格)</code> 布局。</p><p><em>Grid</em> 布局 比 <em>Flex</em> 布局, 从一维到二维。</p><h2 id="相关术语"><a href="#相关术语" class="headerlink" title="相关术语"></a>相关术语</h2><ol><li><code>网格容器(Grid Container)</code>: 应用 <code>display: grid</code> 的元素.</li><li><code>网格项(Grid Item)</code>: 网格容器(Grid Container)的子元素(直接子元素).</li><li><code>网格线(Grid Line)</code>: 构成网格结构的分界线。它们既可以是垂直的(“列网格线(column grid lines)”),也可以是水平的(“行网格线(row grid lines)”),并位于行或列的任一侧。</li><li><code>网格轨道(Grid Track)</code>: 两条<code>相邻网格线</code>之间的空间。你可以把它们想象成网格的列或行。</li><li><code>网格单元格(Grid Cell)</code>: 两个相邻的行和两个相邻的列网格线之间的空间.</li><li><code>网格区域(Grid Area)</code>: 4条网格线包围的总空间。一个网格区域(Grid Area)可以由任意数量的网格单元格(Grid Cell) 组成。</li></ol><h2 id="主要属性"><a href="#主要属性" class="headerlink" title="主要属性"></a>主要属性</h2><p>Grid 布局的属性分成两类。一类定义在容器上面,称为 <code>容器属性</code>;另一类定义在项目上面,称为 <code>项目属性</code>。</p><h3 id="容器属性"><a href="#容器属性" class="headerlink" title="容器属性"></a>容器属性</h3><h4 id="display-属性"><a href="#display-属性" class="headerlink" title="display 属性"></a>display 属性</h4><ul><li><code>display: grid</code> 指定一个容器采用块级网格布局。</li><li><code>display: inline-grid</code> 指定一个容器采用内联网格布局。</li></ul><h4 id="grid-template-columns-grid-template-rows-属性"><a href="#grid-template-columns-grid-template-rows-属性" class="headerlink" title="grid-template-columns,grid-template-rows 属性"></a>grid-template-columns,grid-template-rows 属性</h4><ul><li><code>grid-template-columns</code>: 属性定义每一列的列宽</li><li><code>grid-template-rows</code>: 属性定义每一行的行高</li></ul><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*定义了两行三列的网格,行高为200px 100px, 列宽都为100px*/</span></span><br><span class="line"></span><br><span class="line"><span class="selector-class">.container</span> {</span><br><span class="line"> <span class="attribute">display</span>: grid;</span><br><span class="line"> <span class="attribute">grid-template-columns</span>: <span class="number">100px</span> <span class="number">100px</span> <span class="number">100px</span>;</span><br><span class="line"> <span class="attribute">grid-template-rows</span>: <span class="number">200px</span> <span class="number">100px</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">/* 除了长度值,也可以使用百分比,或者等份网格容器中可用空间(使用 fr 单位)*/</span></span><br><span class="line"><span class="selector-class">.container</span> {</span><br><span class="line"> <span class="attribute">grid-template-columns</span>: <span class="number">40px</span> <span class="number">50px</span> auto <span class="number">50px</span> <span class="number">40px</span>;</span><br><span class="line"> <span class="attribute">grid-template-rows</span>: <span class="number">25%</span> <span class="number">100px</span> auto;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>如果定义了多个值,可以采用 <code>repeat()</code> 函数</p><p>repeat()接受两个参数,第一个参数是重复的次数,第二个参数是所要重复的值。</p><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="attribute">grid-template-rows</span>: <span class="built_in">repeat</span>(<span class="number">3</span>, <span class="number">33.33%</span>);</span><br><span class="line"><span class="attribute">grid-template-columns</span>: <span class="built_in">repeat</span>(<span class="number">2</span>, <span class="number">100px</span> <span class="number">20px</span> <span class="number">80px</span>);</span><br></pre></td></tr></table></figure><p><code>auto-fill</code> 关键字, 单元格的大小是固定的,但是容器的大小不确定, 可以用 auto-fill 关键字表示自动填充。</p><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="selector-class">.container</span> {</span><br><span class="line"> <span class="attribute">display</span>: grid;</span><br><span class="line"> <span class="attribute">grid-template-columns</span>: <span class="built_in">repeat</span>(auto-fill, <span class="number">100px</span>);</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p><code>fr</code>(fraction 的缩写,意为”片段”) 关键字,等分网格容器剩余可用空间来设置 网格轨道(Grid Track) 的大小。</p><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="selector-class">.container</span> {</span><br><span class="line"> <span class="attribute">grid-template-columns</span>: <span class="number">1</span>fr <span class="number">50px</span> <span class="number">1</span>fr <span class="number">1</span>fr;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p><code>minmax()</code> 关键字, 产生一个长度范围,表示长度就在这个范围之中。它接受两个参数,分别为最小值和最大值。</p><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*minmax(100px, 1fr)表示列宽不小于100px,不大于1fr*/</span></span><br><span class="line"><span class="attribute">grid-template-columns</span>: <span class="number">1</span>fr <span class="number">1</span>fr <span class="built_in">minmax</span>(<span class="number">100px</span>, <span class="number">1</span>fr);</span><br></pre></td></tr></table></figure><h4 id="grid-template-areas-属性"><a href="#grid-template-areas-属性" class="headerlink" title="grid-template-areas 属性"></a>grid-template-areas 属性</h4><p>网格布局允许指定”区域”(area),一个区域由单个或多个单元格组成。grid-template-areas属性用于定义区域。常用布局示例.</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag"><<span class="name">div</span> <span class="attr">class</span>=<span class="string">"container"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">div</span> <span class="attr">class</span>=<span class="string">"item-a"</span>></span><span class="tag"></<span class="name">div</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">div</span> <span class="attr">class</span>=<span class="string">"item-b"</span>></span><span class="tag"></<span class="name">div</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">div</span> <span class="attr">class</span>=<span class="string">"item-c"</span>></span><span class="tag"></<span class="name">div</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">div</span> <span class="attr">class</span>=<span class="string">"item-d"</span>></span><span class="tag"></<span class="name">div</span>></span></span><br><span class="line"><span class="tag"></<span class="name">div</span>></span></span><br></pre></td></tr></table></figure><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="selector-class">.item-a</span> {</span><br><span class="line"> <span class="attribute">grid-area</span>: header;</span><br><span class="line">}</span><br><span class="line"><span class="selector-class">.item-b</span> {</span><br><span class="line"> <span class="attribute">grid-area</span>: main;</span><br><span class="line">}</span><br><span class="line"><span class="selector-class">.item-c</span> {</span><br><span class="line"> <span class="attribute">grid-area</span>: sidebar;</span><br><span class="line">}</span><br><span class="line"><span class="selector-class">.item-d</span> {</span><br><span class="line"> <span class="attribute">grid-area</span>: footer;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="selector-class">.container</span> {</span><br><span class="line"> <span class="attribute">display</span>: grid;</span><br><span class="line"> <span class="attribute">grid-template-columns</span>: <span class="number">100px</span> <span class="number">100px</span> <span class="number">100px</span> <span class="number">100px</span>;</span><br><span class="line"> <span class="attribute">grid-template-rows</span>: <span class="number">100px</span> <span class="number">100px</span> <span class="number">100px</span>;</span><br><span class="line"> <span class="attribute">grid-template-areas</span>: <span class="string">"header header header header"</span></span><br><span class="line"> <span class="string">"main main . sidebar"</span></span><br><span class="line"> <span class="string">"footer footer footer footer"</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h4 id="grid-row-gap-grid-column-gap-grid-gap-属性"><a href="#grid-row-gap-grid-column-gap-grid-gap-属性" class="headerlink" title="grid-row-gap,grid-column-gap,grid-gap 属性"></a>grid-row-gap,grid-column-gap,grid-gap 属性</h4><ul><li><code>grid-row-gap</code> 属性设置行与行的间隔(行间距)</li><li><code>grid-column-gap</code> 属性设置列与列的间隔(列间距)</li><li><code>grid-gap</code> 属性是 grid-column-gap 和 grid-row-gap的合并简写形式。如果grid-gap省略了第二个值,浏览器认为第二个值等于第一个值。</li></ul><p>上述属性将可以删除 <code>grid-</code> 前缀</p><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="selector-class">.container</span> {</span><br><span class="line"> <span class="attribute">grid-row</span>-<span class="attribute">gap</span>: <span class="number">20px</span>;</span><br><span class="line"> <span class="attribute">grid-column</span>-<span class="attribute">gap</span>: <span class="number">20px</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">/*简写*/</span></span><br><span class="line"><span class="selector-class">.container</span> {</span><br><span class="line"> <span class="attribute">grid-gap</span>: <span class="number">20px</span> <span class="number">20px</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h4 id="justify-items-align-items-place-items-属性"><a href="#justify-items-align-items-place-items-属性" class="headerlink" title="justify-items,align-items,place-items 属性"></a>justify-items,align-items,place-items 属性</h4><ul><li><code>justify-items</code> 属性设置 <code>单元格内容</code> 的水平位置(左中右)</li><li><code>align-items</code> 属性设置 <code>单元格内容</code> 的垂直位置(上中下)</li><li><code>place-items</code> 属性是 align-items 属性和 justify-items 属性的合并简写形式。</li></ul><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="selector-class">.container</span> {</span><br><span class="line"> justify-items: start | end | center | stretch;</span><br><span class="line"> <span class="attribute">align-items</span>: start | end | center | stretch;</span><br><span class="line">}</span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">* start:对齐单元格的起始边缘。</span></span><br><span class="line"><span class="comment">* end:对齐单元格的结束边缘。</span></span><br><span class="line"><span class="comment">* center:单元格内部居中。</span></span><br><span class="line"><span class="comment">* stretch:拉伸,占满单元格的整个宽度(默认值)。</span></span><br><span class="line"><span class="comment">*/</span></span><br></pre></td></tr></table></figure><h4 id="justify-content-align-content-place-content-属性"><a href="#justify-content-align-content-place-content-属性" class="headerlink" title="justify-content,align-content,place-content 属性"></a>justify-content,align-content,place-content 属性</h4><ul><li><code>justify-content</code> 属性是整个 <code>内容区域</code> 在容器里面的水平位置(左中右)</li><li><code>align-content</code> 属性是整个 <code>内容区域</code> 的垂直位置(上中下)</li><li><code>place-content</code> 属性是align-content属性和justify-content属性的合并简写形式。</li></ul><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="selector-class">.container</span> {</span><br><span class="line"> <span class="attribute">justify-content</span>: start | end | center | stretch | space-around | space-between | space-evenly;</span><br><span class="line"> <span class="attribute">align-content</span>: start | end | center | stretch | space-around | space-between | space-evenly; </span><br><span class="line">}</span><br></pre></td></tr></table></figure><h4 id="grid-auto-columns-grid-auto-rows-属性"><a href="#grid-auto-columns-grid-auto-rows-属性" class="headerlink" title="grid-auto-columns,grid-auto-rows 属性"></a>grid-auto-columns,grid-auto-rows 属性</h4><p><code>grid-auto-columns</code> 属性和 <code>grid-auto-rows</code> 属性用来设置,浏览器自动创建的多余网格的列宽和行高.</p><h4 id="grid-auto-flow-属性"><a href="#grid-auto-flow-属性" class="headerlink" title="grid-auto-flow 属性"></a>grid-auto-flow 属性</h4><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="attribute">grid-auto-flow</span>: row; <span class="comment">/*先行后列*/</span></span><br><span class="line"><span class="attribute">grid-auto-flow</span>: column; <span class="comment">/*先列后行*/</span></span><br><span class="line"></span><br><span class="line"><span class="attribute">grid-auto-flow</span>: row dense; <span class="comment">/*先行后列,并且尽可能紧密填满,尽量不出现空格。*/</span></span><br><span class="line"><span class="attribute">grid-auto-flow</span>: column dense; <span class="comment">/*先列后行,并且尽可能紧密填满,尽量不出现空格。*/</span></span><br></pre></td></tr></table></figure><h3 id="项目属性"><a href="#项目属性" class="headerlink" title="项目属性"></a>项目属性</h3><h4 id="grid-column-start-grid-column-end-grid-row-start-grid-row-end-属性"><a href="#grid-column-start-grid-column-end-grid-row-start-grid-row-end-属性" class="headerlink" title="grid-column-start,grid-column-end,grid-row-start,grid-row-end 属性"></a>grid-column-start,grid-column-end,grid-row-start,grid-row-end 属性</h4><p>锁定项目位置</p><ul><li><code>grid-column-start</code> 属性:左边框所在的垂直网格线</li><li><code>grid-column-end</code> 属性:右边框所在的垂直网格线</li><li><code>grid-row-start</code> 属性:上边框所在的水平网格线</li><li><code>grid-row-end</code> 属性:下边框所在的水平网格线</li></ul><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="selector-class">.item-1</span> {</span><br><span class="line"> <span class="attribute">grid-column-start</span>: <span class="number">1</span>;</span><br><span class="line"> <span class="attribute">grid-column-end</span>: <span class="number">3</span>;</span><br><span class="line"> <span class="attribute">grid-row-start</span>: <span class="number">2</span>;</span><br><span class="line"> <span class="attribute">grid-row-end</span>: <span class="number">4</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">这四个属性的值还可以使用span关键字,表示"跨越",即左右边框(上下边框)之间跨越多少个网格。</span></span><br><span class="line"><span class="comment">1号项目的左边框距离右边框跨越2个网格。</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="selector-class">.item-1</span> {</span><br><span class="line"> <span class="attribute">grid-column-start</span>: span <span class="number">2</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h4 id="grid-column-grid-row-grid-area-属性"><a href="#grid-column-grid-row-grid-area-属性" class="headerlink" title="grid-column,grid-row,grid-area 属性"></a>grid-column,grid-row,grid-area 属性</h4><ul><li><code>grid-column</code> 属性是 grid-column-start 和 grid-column-end 的合并简写形式</li><li><code>grid-row</code> 属性是 grid-row-start 属性和 grid-row-end 的合并简写形式。</li><li><code>grid-area</code> 属性指定项目放在哪一个区域, 还可用作 grid-row-start、grid-column-start、grid-row-end、grid-column-end 的合并简写形式,直接指定项目的位置。</li></ul><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*用 / 分开 */</span></span><br><span class="line"><span class="selector-class">.item</span> {</span><br><span class="line"> <span class="attribute">grid-column</span>: <span class="number">1</span> / <span class="number">3</span>;</span><br><span class="line"> <span class="attribute">grid-row</span>: / ;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="selector-class">.item</span> {</span><br><span class="line"> <span class="attribute">grid-area</span>: <row-start> / <column-start> / <row-end> / <column-end>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h4 id="justify-self-align-self-place-self-属性"><a href="#justify-self-align-self-place-self-属性" class="headerlink" title="justify-self,align-self,place-self 属性"></a>justify-self,align-self,place-self 属性</h4><ul><li><code>justify-self</code> 属性设置 <code>单元格内容</code> 的水平位置(左中右),跟 justify-items 属性的用法完全一致,但只作用于单个项目。</li><li><code>align-self</code> 属性设置 <code>单元格内容</code> 的垂直位置(上中下),跟 align-items 属性的用法完全一致,也是只作用于单个项目。</li><li><code>place-self</code> 属性是 align-self 属性和 justify-self 属性的合并简写形式。</li></ul><h2 id="CSS3-兼容各种浏览器的前缀"><a href="#CSS3-兼容各种浏览器的前缀" class="headerlink" title="CSS3 兼容各种浏览器的前缀"></a>CSS3 兼容各种浏览器的前缀</h2><ol><li><code>-webkit-</code> <strong>chrome、safari</strong></li><li><code>-moz-</code> <strong>firefox</strong></li><li><code>-ms-</code> <strong>IE</strong></li><li><code>-o-</code> <strong>opera</strong></li></ol><h2 id="相关参考"><a href="#相关参考" class="headerlink" title="相关参考"></a>相关参考</h2><ul><li><a href="http://www.ruanyifeng.com/blog/2019/03/grid-layout-tutorial.html">阮一峰-CSS Grid 网格布局教程</a></li><li><a href="https://www.html.cn/archives/8510">CSS Grid 布局完全指南</a></li></ul>]]></content>
<categories>
<category> CSS </category>
</categories>
<tags>
<tag> Grid </tag>
</tags>
</entry>
<entry>
<title>Axios 发送 post 请求下载文件 blob 流</title>
<link href="/passages/20190606axios%E6%96%87%E4%BB%B6%E4%B8%8B%E8%BD%BD/"/>
<url>/passages/20190606axios%E6%96%87%E4%BB%B6%E4%B8%8B%E8%BD%BD/</url>
<content type="html"><![CDATA[<p>关于下载文件,有时候会分步骤进行。第一步发送 <code>post</code> 请求传递参数,服务端接受请求,查询到对应的 <code>文件id</code>。第二步发送 <code>get</code> 请求,服务端根据传递的文件标识返回文件地址,客户端从而实现下载。</p><p>此文介绍的是利用 <code>Axios</code> 发送 <code>post</code> 请求实现文件下载。服务端返回的为 <code>blob</code> 流的形式。</p><span id="more"></span><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//fileDownload.js</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> axios <span class="keyword">from</span> <span class="string">'axios'</span>;</span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 发送post请求下载文件,返回的为 blob 流</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> {<span class="type">*</span>} url 接口地址</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> {<span class="type">*</span>} data 参数</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> {<span class="type">*</span>} fileName 文件名</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> <span class="keyword">async</span> <span class="keyword">function</span> <span class="title function_">fileDownload</span>(<span class="params">url, data, fileName</span>) {</span><br><span class="line"> axios.<span class="property">defaults</span>.<span class="property">headers</span>.<span class="property">post</span>[<span class="string">'Content-Type'</span>] = <span class="string">'application/json'</span>;</span><br><span class="line"> <span class="keyword">await</span> <span class="title function_">axios</span>({</span><br><span class="line"> <span class="attr">method</span>: <span class="string">'post'</span>,</span><br><span class="line"> <span class="attr">url</span>: url,</span><br><span class="line"> <span class="attr">data</span>: <span class="title class_">JSON</span>.<span class="title function_">stringify</span>(data),</span><br><span class="line"> <span class="attr">responseType</span>: <span class="string">'blob'</span></span><br><span class="line"> }).<span class="title function_">then</span>(<span class="function">(<span class="params">res</span>) =></span> {</span><br><span class="line"> <span class="keyword">const</span> content = res.<span class="property">data</span>;</span><br><span class="line"> <span class="keyword">const</span> contentType = res.<span class="property">headers</span>[<span class="string">'content-type'</span>] || <span class="string">"application/octet-stream"</span>; <span class="comment">// 处理浏览器兼容</span></span><br><span class="line"> <span class="keyword">const</span> blob = <span class="keyword">new</span> <span class="title class_">Blob</span>([content], {<span class="attr">type</span>: contentType});</span><br><span class="line"> <span class="keyword">if</span> (<span class="string">'download'</span> <span class="keyword">in</span> <span class="variable language_">document</span>.<span class="title function_">createElement</span>(<span class="string">'a'</span>)) { <span class="comment">//非ie</span></span><br><span class="line"> <span class="keyword">const</span> fileLink = <span class="variable language_">document</span>.<span class="title function_">createElement</span>(<span class="string">'a'</span>);</span><br><span class="line"> fileLink.<span class="property">download</span> = fileName;</span><br><span class="line"> fileLink.<span class="property">style</span>.<span class="property">display</span> = <span class="string">'none'</span>;</span><br><span class="line"> fileLink.<span class="property">href</span> = <span class="variable constant_">URL</span>.<span class="title function_">createObjectURL</span>(blob);</span><br><span class="line"> <span class="variable language_">document</span>.<span class="property">body</span>.<span class="title function_">appendChild</span>(fileLink);</span><br><span class="line"> fileLink.<span class="title function_">click</span>();</span><br><span class="line"> <span class="variable constant_">URL</span>.<span class="title function_">revokeObjectURL</span>(fileLink.<span class="property">href</span>); <span class="comment">// 释放URL 对象</span></span><br><span class="line"> <span class="variable language_">document</span>.<span class="property">body</span>.<span class="title function_">removeChild</span>(fileLink);</span><br><span class="line"> } <span class="keyword">else</span> { <span class="comment">//ie10+</span></span><br><span class="line"> navigator.<span class="title function_">msSaveBlob</span>(blob, fileName);</span><br><span class="line"> }</span><br><span class="line"> })</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">//具体使用</span></span><br><span class="line"><span class="keyword">import</span> fileDownload <span class="keyword">from</span> <span class="string">'fileDownload'</span>;</span><br><span class="line"><span class="title function_">fileDownload</span>(<span class="string">"url"</span>, <span class="string">"data"</span>, <span class="string">"fileName"</span>).<span class="title function_">then</span>( <span class="function">() =></span> {</span><br><span class="line"> <span class="comment">//可以处理回调,例如下载状态</span></span><br><span class="line">})</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">// 返回pdf 流并预览</span></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> <span class="keyword">async</span> <span class="keyword">function</span> <span class="title function_">pdfPreview</span>(<span class="params">method, url, data, fileName</span>) {</span><br><span class="line"> <span class="keyword">let</span> open;</span><br><span class="line"> <span class="keyword">if</span> (<span class="string">'download'</span> <span class="keyword">in</span> <span class="variable language_">document</span>.<span class="title function_">createElement</span>(<span class="string">'a'</span>)) {</span><br><span class="line"> open = <span class="variable language_">window</span>.<span class="title function_">open</span>(); <span class="comment">//防止拦截</span></span><br><span class="line"> }</span><br><span class="line"> axios.<span class="property">defaults</span>.<span class="property">headers</span>.<span class="property">post</span>[<span class="string">'Content-Type'</span>] = <span class="string">'application/json'</span>;</span><br><span class="line"> <span class="keyword">try</span> {</span><br><span class="line"> <span class="keyword">await</span> <span class="title function_">axios</span>({</span><br><span class="line"> <span class="attr">method</span>: method,</span><br><span class="line"> <span class="attr">url</span>: url,</span><br><span class="line"> <span class="attr">data</span>: <span class="title class_">JSON</span>.<span class="title function_">stringify</span>(data),</span><br><span class="line"> <span class="attr">responseType</span>: <span class="string">'blob'</span></span><br><span class="line"> }).<span class="title function_">then</span>(<span class="function">(<span class="params">res</span>) =></span> {</span><br><span class="line"> <span class="keyword">const</span> content = res.<span class="property">data</span>;</span><br><span class="line"> <span class="keyword">const</span> contentType = res.<span class="property">headers</span>[<span class="string">'content-type'</span>] || <span class="string">"application/pdf"</span>; <span class="comment">// 处理浏览器兼容</span></span><br><span class="line"> <span class="keyword">const</span> blob = <span class="keyword">new</span> <span class="title class_">Blob</span>([content], {<span class="attr">type</span>: contentType});</span><br><span class="line"> <span class="keyword">if</span> (<span class="string">'download'</span> <span class="keyword">in</span> <span class="variable language_">document</span>.<span class="title function_">createElement</span>(<span class="string">'a'</span>)) { <span class="comment">//非ie -ie不支持预览</span></span><br><span class="line"> <span class="keyword">const</span> href = <span class="variable constant_">URL</span>.<span class="title function_">createObjectURL</span>(blob);</span><br><span class="line"> open.<span class="property">location</span> = href;</span><br><span class="line"> } <span class="keyword">else</span> { <span class="comment">//ie10+</span></span><br><span class="line"> navigator.<span class="title function_">msSaveBlob</span>(blob, fileName);</span><br><span class="line"> }</span><br><span class="line"> })</span><br><span class="line"> } <span class="keyword">catch</span>(err) {</span><br><span class="line"> } </span><br><span class="line">}</span><br></pre></td></tr></table></figure>]]></content>
<categories>
<category> 请求 </category>
</categories>
<tags>
<tag> axios </tag>
<tag> 文件下载 </tag>
</tags>
</entry>
<entry>
<title>CSS 实现元素居于页面中间</title>
<link href="/passages/20190529%E5%85%83%E7%B4%A0%E5%B1%85%E4%BA%8E%E9%A1%B5%E9%9D%A2%E6%AD%A3%E4%B8%AD/"/>
<url>/passages/20190529%E5%85%83%E7%B4%A0%E5%B1%85%E4%BA%8E%E9%A1%B5%E9%9D%A2%E6%AD%A3%E4%B8%AD/</url>
<content type="html"><![CDATA[<p>关于 CSS 实现元素居于页面中间,方法汇总记录。</p><span id="more"></span><h2 id="方式一-Flex布局"><a href="#方式一-Flex布局" class="headerlink" title="方式一 Flex布局"></a>方式一 Flex布局</h2><p>此种方式无需定义 <code>元素宽高</code>。</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag"><<span class="name">body</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">div</span>></span>居中div<span class="tag"></<span class="name">div</span>></span></span><br><span class="line"><span class="tag"></<span class="name">body</span>></span></span><br></pre></td></tr></table></figure><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="selector-tag">html</span>, <span class="selector-tag">body</span> {</span><br><span class="line"> <span class="attribute">margin</span>: <span class="number">0</span>;</span><br><span class="line"> <span class="attribute">padding</span>: <span class="number">0</span>;</span><br><span class="line"> <span class="attribute">height</span>: <span class="number">100%</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="selector-tag">body</span> { </span><br><span class="line"> <span class="attribute">display</span>: flex;</span><br><span class="line"> <span class="attribute">justify-content</span>: center;</span><br><span class="line"> <span class="attribute">align-items</span>: center;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="selector-tag">div</span> {</span><br><span class="line"> <span class="attribute">border</span>: <span class="number">1px</span> solid <span class="number">#dddddd</span>;</span><br><span class="line"> <span class="attribute">padding</span>: <span class="number">100px</span>;</span><br><span class="line"> <span class="attribute">background-color</span>:green;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="方式二-定位-未知宽高"><a href="#方式二-定位-未知宽高" class="headerlink" title="方式二 定位-未知宽高"></a>方式二 定位-未知宽高</h2><p>此种方式无需定义 <code>元素宽高</code>。</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag"><<span class="name">body</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">div</span>></span>居中div<span class="tag"></<span class="name">div</span>></span></span><br><span class="line"><span class="tag"></<span class="name">body</span>></span></span><br></pre></td></tr></table></figure><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="selector-tag">html</span>, <span class="selector-tag">body</span> {</span><br><span class="line"> <span class="attribute">margin</span>: <span class="number">0</span>;</span><br><span class="line"> <span class="attribute">padding</span>: <span class="number">0</span>;</span><br><span class="line"> <span class="attribute">height</span>: <span class="number">100%</span>;</span><br><span class="line">}</span><br><span class="line"><span class="selector-tag">body</span> { </span><br><span class="line"> <span class="attribute">position</span>: relative;</span><br><span class="line">}</span><br><span class="line"><span class="selector-tag">div</span> {</span><br><span class="line"> <span class="attribute">position</span>: absolute;</span><br><span class="line"> <span class="attribute">left</span>: <span class="number">50%</span>;</span><br><span class="line"> <span class="attribute">top</span>: <span class="number">50%</span>;</span><br><span class="line"> <span class="attribute">transform</span>: <span class="built_in">translate</span>(-<span class="number">50%</span>, -<span class="number">50%</span>); <span class="comment">/*元素向上向左移动元素高宽的50%,使元素中心在正中*/</span></span><br><span class="line"> <span class="attribute">border</span>: <span class="number">1px</span> solid <span class="number">#dddddd</span>;</span><br><span class="line"> <span class="attribute">padding</span>: <span class="number">100px</span>;</span><br><span class="line"> <span class="attribute">background-color</span>:green;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="方式三-定位-已知宽高"><a href="#方式三-定位-已知宽高" class="headerlink" title="方式三 定位-已知宽高"></a>方式三 定位-已知宽高</h2><p>此种方式需要定义 <code>元素宽高</code>。思路同上,设置 <code>margin-top: -height/2</code>, <code>margin-left: -width/2</code>.</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag"><<span class="name">body</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">div</span>></span>居中div<span class="tag"></<span class="name">div</span>></span></span><br><span class="line"><span class="tag"></<span class="name">body</span>></span></span><br></pre></td></tr></table></figure><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="selector-tag">html</span>, <span class="selector-tag">body</span> {</span><br><span class="line"> <span class="attribute">margin</span>: <span class="number">0</span>;</span><br><span class="line"> <span class="attribute">padding</span>: <span class="number">0</span>;</span><br><span class="line"> <span class="attribute">height</span>: <span class="number">100%</span>;</span><br><span class="line">}</span><br><span class="line"><span class="selector-tag">body</span> { </span><br><span class="line"> <span class="attribute">position</span>: relative;</span><br><span class="line">}</span><br><span class="line"><span class="selector-tag">div</span> {</span><br><span class="line"> <span class="attribute">position</span>: absolute;</span><br><span class="line"> <span class="attribute">left</span>: <span class="number">50%</span>;</span><br><span class="line"> <span class="attribute">top</span>: <span class="number">50%</span>;</span><br><span class="line"> <span class="attribute">width</span>: <span class="number">80px</span>;</span><br><span class="line"> <span class="attribute">margin-left</span>: -<span class="number">40px</span>;</span><br><span class="line"> <span class="attribute">text-align</span>: center;</span><br><span class="line"> <span class="attribute">height</span>: <span class="number">80px</span>;</span><br><span class="line"> <span class="attribute">margin-top</span>: -<span class="number">40px</span>;</span><br><span class="line"> <span class="attribute">line-height</span>: <span class="number">80px</span>;</span><br><span class="line"> <span class="attribute">border</span>: <span class="number">1px</span> solid <span class="number">#dddddd</span>;</span><br><span class="line"> <span class="attribute">background-color</span>:green;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="方式四-换一种定位"><a href="#方式四-换一种定位" class="headerlink" title="方式四 换一种定位"></a>方式四 换一种定位</h2><p>与方式 2, 3 一样,只是换一种定位方式 <code>fixed</code>。</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag"><<span class="name">body</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">div</span>></span>居中div<span class="tag"></<span class="name">div</span>></span></span><br><span class="line"><span class="tag"></<span class="name">body</span>></span></span><br></pre></td></tr></table></figure><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="selector-tag">html</span>, <span class="selector-tag">body</span> {</span><br><span class="line"> <span class="attribute">margin</span>: <span class="number">0</span>;</span><br><span class="line"> <span class="attribute">padding</span>: <span class="number">0</span>;</span><br><span class="line"> <span class="attribute">height</span>: <span class="number">100%</span>;</span><br><span class="line">}</span><br><span class="line"><span class="selector-tag">div</span> {</span><br><span class="line"> <span class="attribute">position</span>: fixed;</span><br><span class="line"> <span class="attribute">left</span>: <span class="number">50%</span>;</span><br><span class="line"> <span class="attribute">top</span>: <span class="number">50%</span>;</span><br><span class="line"> <span class="attribute">transform</span>: <span class="built_in">translate</span>(-<span class="number">50%</span>, -<span class="number">50%</span>);</span><br><span class="line"> <span class="attribute">padding</span>: <span class="number">100px</span>;</span><br><span class="line"> <span class="attribute">border</span>: <span class="number">1px</span> solid <span class="number">#dddddd</span>;</span><br><span class="line"> <span class="attribute">background-color</span>:green;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="方式五-利用-margin"><a href="#方式五-利用-margin" class="headerlink" title="方式五 利用 margin"></a>方式五 利用 margin</h2><p>此种方式需要定义 <code>元素宽高</code>. <code>absolute</code> 定位上下左右为0, 设置 <code>margin:auto</code>.</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag"><<span class="name">body</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">div</span>></span>居中div<span class="tag"></<span class="name">div</span>></span></span><br><span class="line"><span class="tag"></<span class="name">body</span>></span></span><br></pre></td></tr></table></figure><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">* {</span><br><span class="line"> <span class="attribute">margin</span>: <span class="number">0</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="selector-tag">div</span> {</span><br><span class="line"> <span class="attribute">position</span>: absolute;</span><br><span class="line"> <span class="attribute">left</span>: <span class="number">0</span>;</span><br><span class="line"> <span class="attribute">right</span>: <span class="number">0</span>;</span><br><span class="line"> <span class="attribute">top</span>: <span class="number">0</span>;</span><br><span class="line"> <span class="attribute">bottom</span>: <span class="number">0</span>;</span><br><span class="line"> <span class="attribute">margin</span>: auto;</span><br><span class="line"> <span class="attribute">width</span>: <span class="number">200px</span>;</span><br><span class="line"> <span class="attribute">height</span>: <span class="number">200px</span>;</span><br><span class="line"> <span class="attribute">background-color</span>: green;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>]]></content>
<categories>
<category> CSS </category>
</categories>
<tags>
<tag> 元素居中 </tag>
</tags>
</entry>
<entry>
<title>WebSocket</title>
<link href="/passages/websocket/"/>
<url>/passages/websocket/</url>
<content type="html"><![CDATA[<p>对 <code>WebSocket</code> 一种网络通信协议 的初步学习,记录。</p><span id="more"></span><h2 id="关于-WebSocket"><a href="#关于-WebSocket" class="headerlink" title="关于 WebSocket"></a>关于 WebSocket</h2><h3 id="WebSocket-与-Http-?"><a href="#WebSocket-与-Http-?" class="headerlink" title="WebSocket 与 Http ?"></a>WebSocket 与 Http ?</h3><ul><li><code>HTTP</code> 协议有一个缺陷:通信只能由客户端发起, 做不到服务器主动向客户端推送信息。</li></ul><blockquote><p><code>单向请求</code>: 注定了如果服务器有连续的状态变化,客户端要获知就非常麻烦。只能使用 <code>轮询</code>, 每隔一段时候,就发出一个询问,了解服务器有没有新的信息。轮询的效率低,非常浪费资源(因为必须不停连接,或者 HTTP 连接始终打开)</p></blockquote><ul><li><code>WebSocket</code> 协议: 服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的 <code>双向平等</code> 对话,属于服务器推送技术的一种.</li></ul><h2 id="socket-io-示例-Demo"><a href="#socket-io-示例-Demo" class="headerlink" title="socket.io 示例 Demo"></a><code>socket.io</code> 示例 Demo</h2><ol><li>服务端代码 <code>socket.js</code>, <code>node socket.js</code></li></ol><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> http = <span class="built_in">require</span>(<span class="string">'http'</span>);</span><br><span class="line"><span class="keyword">var</span> fs = <span class="built_in">require</span>(<span class="string">'fs'</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">//创建服务器,返回 index.html</span></span><br><span class="line"><span class="keyword">var</span> app = http.<span class="title function_">createServer</span>(<span class="function">(<span class="params">req, res</span>) =></span> {</span><br><span class="line"> fs.<span class="title function_">readFile</span>(<span class="string">'index.html'</span>, <span class="function">(<span class="params">err, data</span>)=></span> {</span><br><span class="line"> <span class="comment">//指定res head 及 data</span></span><br><span class="line"> res.<span class="title function_">writeHead</span>(<span class="number">200</span>, { <span class="string">'Content-Type'</span>: <span class="string">'text/html;charset=utf-8'</span> });</span><br><span class="line"> res.<span class="title function_">end</span>(data);</span><br><span class="line"> })</span><br><span class="line">})</span><br><span class="line"></span><br><span class="line"><span class="comment">//创建连接</span></span><br><span class="line"><span class="keyword">var</span> io = <span class="built_in">require</span>(<span class="string">'socket.io'</span>)(app);</span><br><span class="line">io.<span class="title function_">on</span>(<span class="string">'connection'</span>, <span class="function"><span class="params">client</span> =></span> {</span><br><span class="line"> <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">"连接建立"</span>)</span><br><span class="line"> <span class="comment">//服务器端通过 emit 广播,通过 on 接收广播</span></span><br><span class="line"> client.<span class="title function_">on</span>(<span class="string">'add'</span>, <span class="function"><span class="params">data</span> =></span> { </span><br><span class="line"> <span class="variable language_">console</span>.<span class="title function_">log</span>(data);</span><br><span class="line"> io.<span class="title function_">emit</span>(<span class="string">'to-client'</span>, <span class="string">'我是服务器的数据'</span> + data.<span class="property">client</span>)</span><br><span class="line"> });</span><br><span class="line"></span><br><span class="line">});</span><br><span class="line"></span><br><span class="line">app.<span class="title function_">listen</span>(<span class="number">3000</span>);</span><br></pre></td></tr></table></figure><ol start="2"><li>客户端 <code>index.html</code></li></ol><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta"><!DOCTYPE <span class="keyword">html</span>></span></span><br><span class="line"><span class="tag"><<span class="name">html</span> <span class="attr">lang</span>=<span class="string">"en"</span>></span></span><br><span class="line"><span class="tag"><<span class="name">head</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">meta</span> <span class="attr">charset</span>=<span class="string">"UTF-8"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">meta</span> <span class="attr">name</span>=<span class="string">"viewport"</span> <span class="attr">content</span>=<span class="string">"width=device-width, initial-scale=1.0"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">meta</span> <span class="attr">http-equiv</span>=<span class="string">"X-UA-Compatible"</span> <span class="attr">content</span>=<span class="string">"ie=edge"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">title</span>></span>聊天室1<span class="tag"></<span class="name">title</span>></span></span><br><span class="line"><span class="tag"></<span class="name">head</span>></span></span><br><span class="line"><span class="tag"><<span class="name">body</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">button</span> <span class="attr">id</span>=<span class="string">"button"</span>></span>给服务发送数据<span class="tag"></<span class="name">button</span>></span></span><br><span class="line"><span class="tag"></<span class="name">body</span>></span></span><br><span class="line"><span class="tag"><<span class="name">script</span> <span class="attr">src</span>=<span class="string">"http://localhost:3000/socket.io/socket.io.js"</span>></span><span class="tag"></<span class="name">script</span>></span></span><br><span class="line"><span class="tag"><<span class="name">script</span>></span><span class="language-javascript"></span></span><br><span class="line"><span class="language-javascript"> <span class="keyword">var</span> socket = <span class="title function_">io</span>(<span class="string">'http://localhost:3000'</span>);</span></span><br><span class="line"><span class="language-javascript"> <span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">'button'</span>).<span class="property">onclick</span> = <span class="keyword">function</span>(<span class="params"></span>) {</span></span><br><span class="line"><span class="language-javascript"> socket.<span class="title function_">emit</span>(<span class="string">'add'</span>, {</span></span><br><span class="line"><span class="language-javascript"> <span class="string">'client'</span>: <span class="string">'我是客户端的数据'</span></span></span><br><span class="line"><span class="language-javascript"> })</span></span><br><span class="line"><span class="language-javascript"> }</span></span><br><span class="line"><span class="language-javascript"> <span class="comment">//监听服务端的广播</span></span></span><br><span class="line"><span class="language-javascript"> socket.<span class="title function_">on</span>(<span class="string">'to-client'</span>, <span class="keyword">function</span>(<span class="params">data</span>){</span></span><br><span class="line"><span class="language-javascript"> <span class="variable language_">console</span>.<span class="title function_">log</span>(data);</span></span><br><span class="line"><span class="language-javascript"> })</span></span><br><span class="line"><span class="language-javascript"></span><span class="tag"></<span class="name">script</span>></span> </span><br><span class="line"><span class="tag"></<span class="name">html</span>></span></span><br></pre></td></tr></table></figure><h2 id="相关资料"><a href="#相关资料" class="headerlink" title="相关资料"></a>相关资料</h2><ul><li><a href="http://www.ruanyifeng.com/blog/2017/05/websocket.html">WebSocket 教程-阮一峰</a></li><li><a href="https://www.w3cschool.cn/socket/socket-1olq2egc.html">socket.io教程-w3c</a></li><li><a href="https://www.jianshu.com/p/9d8b2e42328c">Vue中使用Websocket</a></li></ul>]]></content>
<categories>
<category> 请求 </category>
</categories>
<tags>
<tag> WebSocket </tag>
</tags>
</entry>
<entry>
<title>vue-cli + nodejs + mongodb 基础</title>
<link href="/passages/vuecli+nodejs+mongodb/"/>
<url>/passages/vuecli+nodejs+mongodb/</url>
<content type="html"><![CDATA[<p>使用 <code>vue-cli</code> 搭建工程,配合 <code>nodejs + mongodb</code> 作为后端服务, 基本流程记录。</p><span id="more"></span><h2 id="环境准备"><a href="#环境准备" class="headerlink" title="环境准备"></a>环境准备</h2><ul><li>vue</li><li>nodejs</li><li>mongodb</li></ul><ol><li><p>下载安装 <code>mongodb</code> <a href="https://www.mongodb.com/download-center/community">mongodb下载</a><br>根据系统选择下载即可,下载 <code>.msi</code> 文件,按照提示安装即可,可以点击 <code>Custom(自定义)</code> 修改安装目录等。注: 安装过层中由于没有去掉 <code>install mongoDB compass</code> 的勾选,则会很慢,因为在下载安装这个 <code>GUI</code>.</p><p>启动:<code>cd E:\mongodb\bin></code>, 输入 <code>mongo.exe</code>,发现启动失败,输入 <code>mongod.exe</code>, 发现报错原因是缺少对应文件目录。原因是 <code>MongoDB 将数据目录存储在 db 目录下。但是这个数据目录不会主动创建,我们在安装完成后需要创建它。请注意,数据目录应该放在根目录下((如: C:\ 或者 D:\ 等 )。</code>。 这里则创建 <code>E:\data\db</code> 目录。</p><p>后续:命令行 <code>cd E:\mongodb\bin></code>, 输入 <code>mongod.exe</code>, 即发现启动正常,此时使用 <code>MongoDB Compass Community————GUI</code>, 可以正常连接。</p></li><li><p>集成 mongodb, <code>npm install mongoose --save</code>, 连接示例如下:</p> <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//配置mongoose</span></span><br><span class="line"><span class="keyword">var</span> mongoose = <span class="built_in">require</span>(<span class="string">"mongoose"</span>);</span><br><span class="line"></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">connectMongoose</span>(<span class="params">dbName</span>) {</span><br><span class="line"></span><br><span class="line"> <span class="comment">//连接数据库,createConnection支持多个数据库的连接</span></span><br><span class="line"> <span class="keyword">var</span> db = mongoose.<span class="title function_">createConnection</span>(<span class="string">'mongodb://localhost:27017/'</span> + dbName);</span><br><span class="line"></span><br><span class="line"> <span class="comment">// connect 只能连接一个数据库,这里需要连接多个,不合适。</span></span><br><span class="line"> <span class="comment">// mongoose.connect("mongodb://localhost:27017/" + dbName);</span></span><br><span class="line"> <span class="comment">// const db = mongoose.connection;</span></span><br><span class="line"></span><br><span class="line"> <span class="comment">//如果连接失败会执行error回调</span></span><br><span class="line"> db.<span class="title function_">once</span>(<span class="string">"error"</span>, <span class="keyword">function</span> (<span class="params">error</span>) {</span><br><span class="line"> <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">"数据库 "</span> + dbName + <span class="string">" 连接失败:"</span> + error);</span><br><span class="line"> });</span><br><span class="line"> <span class="comment">//如果连接成功会执行open回调</span></span><br><span class="line"> db.<span class="title function_">once</span>(<span class="string">"open"</span>, <span class="keyword">function</span> (<span class="params"></span>) {</span><br><span class="line"> <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">"数据库 "</span> + dbName + <span class="string">" 连接成功"</span>);</span><br><span class="line"> });</span><br><span class="line"></span><br><span class="line"> <span class="comment">//return mongoose;</span></span><br><span class="line"> <span class="keyword">return</span> db;</span><br><span class="line">}</span><br><span class="line"></span><br></pre></td></tr></table></figure></li><li><p>集成 nodejs (express), <code>npm install express --save</code>, 示例如下:</p> <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> express = <span class="built_in">require</span>(<span class="string">'express'</span>);</span><br><span class="line"><span class="keyword">var</span> path = <span class="built_in">require</span>(<span class="string">'path'</span>);</span><br><span class="line"><span class="keyword">var</span> bodyParser = <span class="built_in">require</span>(<span class="string">'body-parser'</span>); <span class="comment">//req.body本来为undefined, 引入此 body-parsing middleware</span></span><br><span class="line"><span class="keyword">var</span> cookieParser = <span class="built_in">require</span>(<span class="string">'cookie-parser'</span>); <span class="comment">//cookie格式化</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> app = <span class="title function_">express</span>();</span><br><span class="line">app.<span class="title function_">use</span>(bodyParser.<span class="title function_">json</span>()); <span class="comment">//for parsing application/json</span></span><br><span class="line">app.<span class="title function_">use</span>(bodyParser.<span class="title function_">urlencoded</span>({ <span class="attr">extended</span>: <span class="literal">true</span> })); <span class="comment">// for parsing application/x-www-form-urlencoded</span></span><br><span class="line">app.<span class="title function_">use</span>(<span class="title function_">cookieParser</span>());</span><br><span class="line"></span><br><span class="line"><span class="comment">//设置静态资源目录</span></span><br><span class="line">app.<span class="title function_">use</span>(express.<span class="title function_">static</span>(path.<span class="title function_">join</span>(__dirname, <span class="string">'../dist'</span>)));</span><br><span class="line"></span><br><span class="line"><span class="comment">//所有访问,都指定返回 index.html</span></span><br><span class="line">app.<span class="title function_">get</span>(<span class="string">'/*'</span>, <span class="keyword">function</span> (<span class="params">req, res</span>) {</span><br><span class="line"> res.<span class="title function_">sendFile</span>(path.<span class="title function_">join</span>(__dirname, <span class="string">'../dist'</span>, <span class="string">'index.html'</span>));</span><br><span class="line">});</span><br><span class="line"></span><br><span class="line"><span class="comment">//设置服务器</span></span><br><span class="line"><span class="keyword">var</span> server = app.<span class="title function_">listen</span>(<span class="number">3000</span>, <span class="keyword">function</span> (<span class="params"></span>) {</span><br><span class="line"> <span class="keyword">var</span> host = server.<span class="title function_">address</span>().<span class="property">address</span>;</span><br><span class="line"> <span class="keyword">var</span> port = server.<span class="title function_">address</span>().<span class="property">port</span>;</span><br><span class="line"> <span class="comment">// eslint-disable-next-line no-console</span></span><br><span class="line"> <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">'server listening at http://%s:%s'</span>, host, port);</span><br><span class="line">});</span><br></pre></td></tr></table></figure></li></ol><h2 id="后续使用"><a href="#后续使用" class="headerlink" title="后续使用"></a>后续使用</h2><ol><li><p>首先为 <code>node</code> 服务收到请求,通过不同路由(也可以说是接口),连接不同的数据库,进行增删改查等等操作。</p> <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//node服务对应文件中添加路由</span></span><br><span class="line">app.<span class="title function_">use</span>(<span class="string">'/api/login'</span>, <span class="built_in">require</span>(<span class="string">'./routes/login'</span>));</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">//路由文件,后端具体路由(接口)请求数据库,调用不同的方法</span></span><br><span class="line"><span class="keyword">var</span> express = <span class="built_in">require</span>(<span class="string">'express'</span>);</span><br><span class="line"><span class="keyword">var</span> router = express.<span class="title class_">Router</span>();</span><br><span class="line"><span class="keyword">var</span> admin = <span class="built_in">require</span>(<span class="string">'../mongodb/schemas/admin'</span>)</span><br><span class="line"></span><br><span class="line">router.<span class="title function_">post</span>(<span class="string">'/'</span>, <span class="keyword">function</span>(<span class="params">req, res, next</span>) {</span><br><span class="line"> admin.<span class="title function_">selectAdmin</span>(req.<span class="property">body</span>, <span class="keyword">function</span>(<span class="params">docs</span>) {</span><br><span class="line"> res.<span class="title function_">send</span>(docs);</span><br><span class="line"> })</span><br><span class="line">});</span><br><span class="line"><span class="variable language_">module</span>.<span class="property">exports</span> = router;</span><br><span class="line"></span><br><span class="line"><span class="comment">//具体对应数据库的操作,dao层</span></span><br><span class="line"><span class="keyword">var</span> connectMongoose = <span class="built_in">require</span>(<span class="string">"../mongoose"</span>).<span class="property">connectMongoose</span></span><br><span class="line"><span class="comment">//var mongoose = connectMongoose("admin");</span></span><br><span class="line"><span class="comment">//createConnection 创建的不能直接操作 schema, 仍需引入mongoose</span></span><br><span class="line"><span class="keyword">var</span> mongoose = <span class="built_in">require</span>(<span class="string">"mongoose"</span>);</span><br><span class="line"><span class="keyword">var</span> db = <span class="title function_">connectMongoose</span>(<span class="string">"admin"</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">//定义一个 schema,描述此集合里有哪些字段,字段是什么类型</span></span><br><span class="line"><span class="comment">//只有schema中有的属性才能被保存到数据库中</span></span><br><span class="line"><span class="keyword">var</span> adminSchema = <span class="keyword">new</span> mongoose.<span class="title class_">Schema</span>({</span><br><span class="line"> account : { <span class="attr">type</span>: <span class="title class_">String</span> },</span><br><span class="line"> password : { <span class="attr">type</span>: <span class="title class_">String</span> },</span><br><span class="line"> time : { <span class="attr">type</span>: <span class="title class_">Date</span>, <span class="attr">default</span>: <span class="title class_">Date</span>.<span class="property">now</span> },</span><br><span class="line">});</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> adminModel = db.<span class="title function_">model</span>(<span class="string">"person"</span>, adminSchema);</span><br><span class="line"></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">selectAdmin</span>(<span class="params">data, callback</span>) {</span><br><span class="line"> adminModel.<span class="title function_">find</span>({</span><br><span class="line"> <span class="string">'account'</span>: {<span class="string">"$gte"</span>: data.<span class="property">account</span>, <span class="string">"$lte"</span>: data.<span class="property">account</span>},</span><br><span class="line"> <span class="string">'password'</span>: {<span class="string">"$gte"</span>: data.<span class="property">password</span>, <span class="string">"$lte"</span>: data.<span class="property">password</span>}</span><br><span class="line"> },</span><br><span class="line"> {<span class="attr">account</span>: <span class="number">1</span>, <span class="attr">password</span>: <span class="number">1</span>},</span><br><span class="line"> <span class="keyword">function</span>(<span class="params">err,docs</span>) {</span><br><span class="line"> <span class="title function_">callback</span>(docs);</span><br><span class="line"> })</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="variable language_">module</span>.<span class="property">exports</span> = {</span><br><span class="line"> <span class="string">"selectAdmin"</span> : selectAdmin</span><br><span class="line">}</span><br></pre></td></tr></table></figure></li><li><p>上述 <code>node->mongodb</code> 已走通, 下述从 <code>vue->node</code> 的流程。</p> <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//vue.config.js , 需要配置代理到node</span></span><br><span class="line"><span class="variable language_">module</span>.<span class="property">exports</span> = {</span><br><span class="line"> <span class="attr">devServer</span>: {</span><br><span class="line"> <span class="attr">proxy</span>: {</span><br><span class="line"> <span class="string">"^/api"</span>: {</span><br><span class="line"> <span class="attr">target</span>: <span class="string">"http://localhost:3000"</span>,</span><br><span class="line"> <span class="attr">ws</span>: <span class="literal">true</span>,</span><br><span class="line"> <span class="attr">changeOrigin</span>: <span class="literal">true</span></span><br><span class="line"> }</span><br><span class="line"> },</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">//vue 文件</span></span><br><span class="line"><span class="keyword">import</span> {login} <span class="keyword">from</span> <span class="string">'@/request/api'</span>;</span><br><span class="line"><span class="keyword">async</span> <span class="title function_">login</span>(<span class="params">data</span>) {</span><br><span class="line"> <span class="keyword">let</span> res = <span class="keyword">await</span> <span class="title function_">login</span>(data);</span><br><span class="line">}</span><br><span class="line"><span class="variable language_">this</span>.<span class="title function_">login</span>(data);</span><br><span class="line"></span><br><span class="line"><span class="comment">//api.js</span></span><br><span class="line"><span class="keyword">import</span> {post} <span class="keyword">from</span> <span class="string">'./request'</span>;</span><br><span class="line"><span class="keyword">export</span> <span class="keyword">function</span> <span class="title function_">login</span>(<span class="params">data</span>) {</span><br><span class="line"> <span class="keyword">return</span> <span class="title function_">post</span>(<span class="string">'/api/login'</span>, data);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">//request.js</span></span><br><span class="line"><span class="comment">//此处不做粘贴,是对 `axios` 的一个封装</span></span><br></pre></td></tr></table></figure></li><li><p>至此,<code>vue</code> 通过 <code>axios</code> 发送请求,然后被代理到 <code>node</code> 服务,通过 <code>express</code> 的 路由转发,去请求数据库做一些列操作,完成。</p></li></ol><h2 id="上述代码见项目"><a href="#上述代码见项目" class="headerlink" title="上述代码见项目"></a>上述代码见项目</h2><p><a href="https://github.com/zzugbb/vue/tree/master/my-manage-system">my-manage-system</a></p><h2 id="参考"><a href="#参考" class="headerlink" title="参考"></a>参考</h2><ul><li><a href="https://my.oschina.net/AndyShang/blog/865875">在vue-cli中引入mongodb数据库</a></li><li><a href="https://www.cnblogs.com/web-fengmin/p/6435681.html">mongoDB与mongoose</a></li><li><a href="https://blog.csdn.net/younglao/article/details/76443726">mongoose中connect()、createConnection()和connection的区别和作用</a></li><li><a href="https://mongoosejs.com/docs/api.html#mongoose_Mongoose">mongoose 官方 api</a></li></ul>]]></content>
<categories>
<category> Vue </category>
</categories>
<tags>
<tag> vue-cli </tag>
<tag> nodejs </tag>
<tag> mongodb </tag>
</tags>
</entry>
<entry>
<title>个人手记(一)</title>
<link href="/passages/20190327%E4%B8%AA%E4%BA%BA%E6%89%8B%E8%AE%B0/"/>
<url>/passages/20190327%E4%B8%AA%E4%BA%BA%E6%89%8B%E8%AE%B0/</url>
<content type="html"><![CDATA[<p>2019.3.27 随手记 <i class="fa fa-empire" aria-hidden="true"></i></p><span id="more"></span><h2 id="个人经历"><a href="#个人经历" class="headerlink" title="个人经历"></a>个人经历</h2><p>新的环境需要努力,加油!,不知所云~~~ <i class="fa fa-gratipay" aria-hidden="true"></i></p>]]></content>
<categories>
<category> 手记 </category>
</categories>
<tags>
<tag> 个人手记 </tag>
</tags>
</entry>
<entry>
<title>面试常见问题(二)</title>
<link href="/passages/%E9%9D%A2%E8%AF%95%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98%EF%BC%88%E4%BA%8C%EF%BC%89/"/>
<url>/passages/%E9%9D%A2%E8%AF%95%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98%EF%BC%88%E4%BA%8C%EF%BC%89/</url>
<content type="html"><![CDATA[<p>前端面试的常见问题记录, ajax, http && https, 响应式布局, cookie/session 等。</p><span id="more"></span><h2 id="AJAX"><a href="#AJAX" class="headerlink" title="AJAX"></a>AJAX</h2><h3 id="什么是-AJAX-?"><a href="#什么是-AJAX-?" class="headerlink" title="什么是 AJAX ?"></a>什么是 AJAX ?</h3><blockquote><p><code>AJAX</code> 全称为 <code>Asynchronous JavaScript and XML</code>(异步JavaScript和XML),是一种创建交互式网页应用的网页开发技术。</p></blockquote><ul><li>AJAX 不是新的编程语言,而是一种使用现有标准的新方法。</li><li>AJAX 最大的优点是在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容。</li><li>AJAX 不需要任何浏览器插件,但需要用户允许JavaScript在浏览器上执行。</li></ul><h3 id="AJAX-的优点"><a href="#AJAX-的优点" class="headerlink" title="AJAX 的优点"></a>AJAX 的优点</h3><ol><li><code>无刷新更新数据</code>, 不刷新整个页面的前提下与服务器通信维护数据, 减少用户等待时间, 更好的用户体验。</li><li><code>异步与服务器通信</code>, 不需要打断用户的操作,具有更加迅速的响应能力</li><li><code>前端和后端负载平衡</code>, 最大程度的减少冗余请求和响应对服务器造成的负担,提升站点性能。</li><li><code>基于标准被广泛支持</code>。</li><li><code>界面与应用分离</code>, 有利于分工合作、减少非技术人员对页面的修改造成的WEB应用程序错误、提高效率、也更加适用于现在的发布系统。</li></ol><h3 id="AJAX-的缺点"><a href="#AJAX-的缺点" class="headerlink" title="AJAX 的缺点"></a>AJAX 的缺点</h3><ol><li><code>back和History,对浏览器机制的破坏</code>。</li><li><code>安全问题</code>, 跨站点脚步攻击、SQL注入攻击</li><li><code>对搜索引擎支持较弱</code></li><li><code>违背URL和资源定位的初衷</code></li><li>等…</li></ol><h2 id="Http-amp-amp-Https"><a href="#Http-amp-amp-Https" class="headerlink" title="Http && Https"></a>Http && Https</h2><h3 id="什么是-Http-Https-?"><a href="#什么是-Http-Https-?" class="headerlink" title="什么是 Http , Https ?"></a>什么是 Http , Https ?</h3><blockquote><p>HTTP(HyperText Transfer Protocol:超文本传输协议)是一种用于分布式、协作式和超媒体信息系统的应用层协议。 简单来说就是一种发布和接收 HTML 页面的方法,被用于在 Web 浏览器和网站服务器之间传递信息。</p></blockquote><blockquote><p>HTTPS(Hypertext Transfer Protocol Secure:超文本传输安全协议)是一种透过计算机网络进行安全通信的传输协议。HTTPS 经由 HTTP 进行通信,但利用 SSL/TLS 来加密数据包。HTTPS 开发的主要目的,是提供对网站服务器的身份认证,保护交换数据的隐私与完整性。</p></blockquote><h3 id="Http-Https-区别?"><a href="#Http-Https-区别?" class="headerlink" title="Http , Https 区别?"></a>Http , Https 区别?</h3><ul><li>HTTP 明文传输,数据都是未加密的,安全性较差,HTTPS(SSL+HTTP) 数据传输过程是加密的,安全性较好。</li><li>使用 HTTPS 协议需要到 CA(Certificate Authority,数字证书认证机构) 申请证书,一般免费证书较少,因而需要一定费用。证书颁发机构如:Symantec、Comodo、GoDaddy 和 GlobalSign 等。</li><li>HTTP 页面响应速度比 HTTPS 快,主要是因为 HTTP 使用 TCP 三次握手建立连接,客户端和服务器需要交换 3 个包,而 HTTPS除了 TCP 的三个包,还要加上 ssl 握手需要的 9 个包,所以一共是 12 个包。</li><li>http 和 https 使用的是完全不同的连接方式,用的端口也不一样,前者是 80,后者是 443。</li><li>HTTPS 其实就是建构在 SSL/TLS 之上的 HTTP 协议,所以,HTTPS 比 HTTP 要更耗费服务器资源。</li></ul><h2 id="cookie-session"><a href="#cookie-session" class="headerlink" title="cookie, session"></a>cookie, session</h2><p><code>cookie</code> 机制采用的是在 <code>客户端保持状态</code> 的方案,而 <code>session</code> 机制采用的是在 <code>服务器端保持状态</code> 的方案。</p><blockquote><p>Cookie 是一些数据, 存储于你电脑上的文本文件中, 当 web 服务器向浏览器发送 web 页面时,在连接关闭后,服务端不会记录用户的信息。</p></blockquote><p>Cookie 的作用就是用于解决 “如何记录客户端的用户信息”:</p><ul><li>当用户访问 web 页面时,他的名字可以记录在 cookie 中。</li><li>在用户下一次访问该页面时,可以在 cookie 中读取用户访问记录。</li></ul><blockquote><p>Session 是另一种记录客户状态的机制,不同的是Cookie保存在客户端浏览器中,而Session保存在服务器上。客户端浏览器访问服务器的时候,服务器把客户端信息以某种形式记录在服务器上, 这就是Session。客户端浏览器再次访问时只需要从该Session中查找该客户的状态就可以了。</p></blockquote><h2 id="响应式布局"><a href="#响应式布局" class="headerlink" title="响应式布局"></a>响应式布局</h2><blockquote><p><code>响应式布局</code> 意在实现不同屏幕分辨率的终端上浏览网页的不同展示方式。通过响应式设计能使网站在手机和平板电脑上有更好的浏览阅读体验。</p></blockquote><blockquote><p><code>RWD-响应式网站设计</code> (简称RWD)是一种新的网站设计模式,以此构建的网站可自动适应不同的访问设备(从桌面电脑、平板电脑到智能手机),方便用户阅读和导航浏览,减少用户的放大/缩小/滑动操作,从而提供完整而友好的用户体验。</p></blockquote><h3 id="RWD-关键"><a href="#RWD-关键" class="headerlink" title="RWD 关键"></a>RWD 关键</h3><ol><li><code>media query</code>, 基于 RWD 设计的网站利用CSS3 media query规则来自动适应不同访问设备的屏幕尺寸和显示要求.</li><li><code>流动网格</code>, 采用页面元素大小的相对单位(百分比或EM),而非传统设计使用的绝对单位(像素或点数),以确定页面各组成元素的大小.</li><li><code>灵活缩放的图片</code>, 不至于在小屏幕的移动设备上超出显示区域.</li></ol><h2 id="参考"><a href="#参考" class="headerlink" title="参考"></a>参考</h2><ul><li><a href="https://www.cnblogs.com/yelp/p/3725664.html">AJAX工作原理及其优缺点</a></li><li><a href="http://www.runoob.com/w3cnote/http-vs-https.html">HTTP 与 HTTPS 的区别</a></li><li><a href="https://www.jianshu.com/p/6baa79ab9393">响应式网页设计</a></li></ul>]]></content>
<categories>
<category> 面试 </category>
</categories>
<tags>
<tag> HTTPS </tag>
<tag> AJAX </tag>
<tag> cookie/session </tag>
<tag> 响应式布局 </tag>
</tags>
</entry>
<entry>
<title>Mocha-单元测试</title>
<link href="/passages/%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95-Mocha/"/>
<url>/passages/%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95-Mocha/</url>
<content type="html"><![CDATA[<p>前端开发过程中,测试有着非常重要的角色, 分为 <code>单元测试</code>, <code>功能测试</code>, 等等,本文主要记录对 <code>单元测试框架-Mocha</code> 的学习。</p><span id="more"></span><h2 id="关于-Mocha"><a href="#关于-Mocha" class="headerlink" title="关于 Mocha"></a>关于 Mocha</h2><blockquote><p><code>Mocha</code> 是 <code>JavaScript</code> 的一种单元测试框架,既可以在 <code>浏览器</code> 环境下运行,也可以在 <code>Node.js</code> 环境下运行。使用 <code>Mocha</code> ,我们就只需要专注于编写单元测试本身,然后,让 <code>Mocha</code> 去自动运行所有的测试,并给出测试结果。</p></blockquote><p>Mocha 的特点:</p><ul><li>既可以测试简单的JavaScript函数,又可以测试异步代码,因为异步是JavaScript的特性之一;</li><li>可以自动运行所有测试,也可以只运行特定的测试;</li><li>可以支持before、after、beforeEach和afterEach来编写初始化代码。</li></ul><h2 id="Mocha-的使用"><a href="#Mocha-的使用" class="headerlink" title="Mocha 的使用"></a>Mocha 的使用</h2><h3 id="安装"><a href="#安装" class="headerlink" title="安装"></a>安装</h3><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 全局安装</span></span><br><span class="line">npm install mocha -g</span><br><span class="line"></span><br><span class="line"><span class="comment"># 安装 mocha</span></span><br><span class="line">npm install --save-dev mocha</span><br><span class="line"></span><br><span class="line"><span class="comment"># 安装chai-断言 也可选择其它</span></span><br><span class="line">npm install --save-dev chai</span><br></pre></td></tr></table></figure><h3 id="使用"><a href="#使用" class="headerlink" title="使用"></a>使用</h3><p><code>add.js</code></p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">add</span>(<span class="params">x, y</span>) {</span><br><span class="line"> <span class="keyword">return</span> x + y;</span><br><span class="line">}</span><br><span class="line"><span class="variable language_">module</span>.<span class="property">exports</span> = add;</span><br></pre></td></tr></table></figure><p>测试脚本 <code>add.test.js</code></p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> add = <span class="built_in">require</span>(<span class="string">'./add.js'</span>);</span><br><span class="line"><span class="keyword">var</span> expect = <span class="built_in">require</span>(<span class="string">'chai'</span>).<span class="property">expect</span>;</span><br><span class="line"></span><br><span class="line"><span class="title function_">describe</span>(<span class="string">'加法函数的测试'</span>, <span class="keyword">function</span>(<span class="params"></span>) {</span><br><span class="line"> <span class="title function_">it</span>(<span class="string">'1 加 1 应该等于 2'</span>, <span class="keyword">function</span>(<span class="params"></span>) {</span><br><span class="line"> <span class="title function_">expect</span>(<span class="title function_">add</span>(<span class="number">1</span>, <span class="number">1</span>)).<span class="property">to</span>.<span class="property">be</span>.<span class="title function_">equal</span>(<span class="number">2</span>);</span><br><span class="line"> });</span><br><span class="line">});</span><br></pre></td></tr></table></figure><p>测试脚本与所要测试的源码脚本同名,但是后缀名为 <code>.test.js</code>(表示测试).</p><p>测试脚本里面应该包括一个或多个 <code>describe</code> 块,每个 <code>describe</code> 块应该包括一个或多个 <code>it</code> 块。</p><p><code>describe</code> 块称为”测试套件”(test suite),表示一组相关的测试。它是一个函数,第一个参数是测试套件的名称(”加法函数的测试”),第二个参数是一个实际执行的函数。</p><p><code>it</code> 块称为”测试用例”(test case),表示一个单独的测试,是测试的最小单位。它也是一个函数,第一个参数是测试用例的名称(”1 加 1 应该等于 2”),第二个参数是一个实际执行的函数。</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//断言</span></span><br><span class="line"><span class="title function_">expect</span>(<span class="title function_">add</span>(<span class="number">1</span>, <span class="number">1</span>)).<span class="property">to</span>.<span class="property">be</span>.<span class="title function_">equal</span>(<span class="number">2</span>)</span><br></pre></td></tr></table></figure><p>所谓”断言”,就是判断源码的实际执行结果与预期结果是否一致,如果不一致就抛出一个错误。上面这句断言的意思是,调用add(1, 1),结果应该等于2。</p><p>所有的测试用例( <code>it</code> 块)都应该含有一句或多句的断言。它是编写测试用例的关键。断言功能由断言库来实现,Mocha本身不带断言库,所以必须先引入断言库。</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> expect = <span class="built_in">require</span>(<span class="string">'chai'</span>).<span class="property">expect</span>;</span><br></pre></td></tr></table></figure><p>断言库有很多种,Mocha并不限制使用哪一种。上面代码引入的断言库是 <code>chai</code>,并且指定使用它的 <code>expect</code> 断言风格.</p><h3 id="使用命令"><a href="#使用命令" class="headerlink" title="使用命令"></a>使用命令</h3><figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">"scripts"</span><span class="punctuation">:</span> <span class="punctuation">{</span></span><br><span class="line"> <span class="attr">"test"</span><span class="punctuation">:</span> <span class="string">"mocha"</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"test-all"</span> <span class="punctuation">:</span> <span class="string">"mocha --recursive"</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"test-js"</span><span class="punctuation">:</span> <span class="string">"mocha *.test.js"</span></span><br><span class="line"><span class="punctuation">}</span><span class="punctuation">,</span></span><br></pre></td></tr></table></figure><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">npm <span class="built_in">test</span> <span class="comment"># Mocha 默认运行 test 子目录里面的测试脚本, test目录的子目录里面的测试脚本不会运行</span></span><br><span class="line">npm run test-all <span class="comment"># Mocha 默认运行 test 子目录里面的测试脚本, test下所有,包含子目录</span></span><br><span class="line">npm run test-js <span class="comment"># Mocha 运行所有根目录下 以 .test.js 的测试脚本</span></span><br></pre></td></tr></table></figure><h3 id="关于异步"><a href="#关于异步" class="headerlink" title="关于异步"></a>关于异步</h3><p><code>Mocha</code> 默认每个测试用例最多执行 <code>2000</code> 毫秒.</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 改变默认的超时设置</span></span><br><span class="line">mocha -t 5000 timeout.test.js</span><br></pre></td></tr></table></figure><p><code>Mocha</code> 内置对 <code>Promise</code> 的支持,允许直接返回 <code>Promise</code>,等到它的状态改变,再执行断言,而不用显式调用 <code>done</code> 方法。</p><h3 id="测试用例的钩子"><a href="#测试用例的钩子" class="headerlink" title="测试用例的钩子"></a>测试用例的钩子</h3><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="title function_">describe</span>(<span class="string">'hooks'</span>, <span class="keyword">function</span>(<span class="params"></span>) {</span><br><span class="line"> <span class="title function_">before</span>(<span class="keyword">function</span>(<span class="params"></span>) {</span><br><span class="line"> <span class="comment">// 在本区块的所有测试用例之前执行</span></span><br><span class="line"> });</span><br><span class="line"></span><br><span class="line"> <span class="title function_">after</span>(<span class="keyword">function</span>(<span class="params"></span>) {</span><br><span class="line"> <span class="comment">// 在本区块的所有测试用例之后执行</span></span><br><span class="line"> });</span><br><span class="line"></span><br><span class="line"> <span class="title function_">beforeEach</span>(<span class="keyword">function</span>(<span class="params"></span>) {</span><br><span class="line"> <span class="comment">// 在本区块的每个测试用例之前执行</span></span><br><span class="line"> });</span><br><span class="line"></span><br><span class="line"> <span class="title function_">afterEach</span>(<span class="keyword">function</span>(<span class="params"></span>) {</span><br><span class="line"> <span class="comment">// 在本区块的每个测试用例之后执行</span></span><br><span class="line"> });</span><br><span class="line"></span><br><span class="line"> <span class="comment">// test cases</span></span><br><span class="line">});</span><br><span class="line"></span><br></pre></td></tr></table></figure><h3 id="测试用例管理"><a href="#测试用例管理" class="headerlink" title="测试用例管理"></a>测试用例管理</h3><p>大型项目有很多测试用例, 有时,我们希望只运行其中的几个,这时可以用 <code>only</code> 方法。<code>describe</code> 块和 <code>it</code> 块都允许调用 <code>only</code> 方法,表示只运行某个测试套件或测试用例。</p><p>此外,还有 <code>skip</code> 方法,表示跳过指定的测试套件或测试用例。</p><h2 id="断言"><a href="#断言" class="headerlink" title="断言"></a>断言</h2><blockquote><p>所谓”断言”,就是判断源码的实际执行结果与预期结果是否一致.</p></blockquote><p>所有的测试用例(it块)都应该含有一句或多句的断言, 它是编写测试用例的关键。断言功能由断言库来实现,Mocha本身不带断言库,所以必须先引入断言库。</p><p>断言库有很多种,Mocha并不限制使用哪一种。上面代码引入的断言库是 <code>chai</code>,并且指定使用它的 <code>expect</code> 断言风格。</p><p>基本上,<code>expect</code> 断言的写法都是一样的。头部是 <code>expect</code> 方法,尾部是 断言方法,比如 <code>equal、a/an、ok、match</code> 等。两者之间使用 <code>to</code> 或<code>to.be</code> 连接。</p><h2 id="具体demo"><a href="#具体demo" class="headerlink" title="具体demo"></a>具体demo</h2><ul><li><a href="https://github.com/zzugbb/js-test/tree/master/Mocha-demo">Mocha-demo</a></li></ul><h2 id="参考"><a href="#参考" class="headerlink" title="参考"></a>参考</h2><ul><li><a href="https://www.liaoxuefeng.com/wiki/001434446689867b27157e896e74d51a89c25cc8b43bdb3000/00147203593334596b366f3fe0b409fbc30ad81a0a91c4a000">廖雪峰的官方网站-mocha</a></li><li><a href="https://github.com/ruanyf/jstraining/blob/master/demos/README.md#mocha">JavaScript 全栈工程师培训教程-Mocha-阮一峰</a></li><li><a href="https://www.jianshu.com/p/52b8aabe51dc">javascript单元测试-mocha</a></li><li><a href="https://mochajs.org/">mocha-官网</a></li><li><a href="https://www.chaijs.com/">chai-官网</a></li></ul>]]></content>
<categories>
<category> 测试 </category>
</categories>
<tags>
<tag> Mocha </tag>
<tag> 单元测试 </tag>
</tags>
</entry>
<entry>
<title>Travis CI (持续集成)</title>
<link href="/passages/Travis%20CI/"/>
<url>/passages/Travis%20CI/</url>
<content type="html"><![CDATA[<blockquote><p><code>持续集成</code>(英语:Continuous integration,缩写 CI)是一种软件工程流程,是将所有软件工程师对于软件的工作副本持续集成到共享主线(mainline)的一种举措。</p></blockquote><span id="more"></span><h2 id="持续集成"><a href="#持续集成" class="headerlink" title="持续集成"></a>持续集成</h2><blockquote><p><code>持续集成</code>(英语:Continuous integration,缩写 CI)是一种软件工程流程,是将所有软件工程师对于软件的工作副本持续集成到共享主线(mainline)的一种举措。</p></blockquote><p><img src="https://travis-ci.org/zzugbb/my-gitbook.svg?branch=master" alt="build:passed"></p><h2 id="具体实战"><a href="#具体实战" class="headerlink" title="具体实战"></a>具体实战</h2><p><a href="https://zzugbb.github.io/my-gitbook/CI.html">gitbook 使用 Travis CI 实现自动部署</a></p><p><a href="https://zzugbb.github.io/my-gitbook/">gitbook 使用 – my-gitbook</a></p><p><a href="https://github.com/zzugbb/my-gitbook">my-gitbook</a></p>]]></content>
<categories>
<category> 工程部署 </category>
</categories>
<tags>
<tag> 持续集成 </tag>
<tag> Travis CI </tag>
</tags>
</entry>
<entry>
<title>面试常见问题(一)</title>
<link href="/passages/%E9%9D%A2%E8%AF%95%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98%EF%BC%88%E4%B8%80%EF%BC%89/"/>
<url>/passages/%E9%9D%A2%E8%AF%95%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98%EF%BC%88%E4%B8%80%EF%BC%89/</url>
<content type="html"><![CDATA[<p>前端面试的常见问题记录,闭包,继承</p><span id="more"></span><h2 id="JavaScript-闭包"><a href="#JavaScript-闭包" class="headerlink" title="JavaScript 闭包"></a>JavaScript 闭包</h2><blockquote><p><code>闭包</code> 是指有权访问另一个函数作用域中的变量的函数(能够读取其他函数内部变量的函数)。创建闭包的常见方式,就是在一个函数内部创建另一个函数。</p></blockquote><p>一个函数的返回值是另一个函数,而返回的这个函数如果调用了其父函数内部的其它变量,且返回的这个函数在外部被执行,就产生了闭包。</p><p>表现形式: 函数外部能调用函数内部定义的变量。</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">makeFunc</span>(<span class="params"></span>) {</span><br><span class="line"> <span class="keyword">var</span> name = <span class="string">"Mozilla"</span>;</span><br><span class="line"> <span class="keyword">function</span> <span class="title function_">displayName</span>(<span class="params"></span>) {</span><br><span class="line"> <span class="title function_">alert</span>(name);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> displayName; <span class="comment">//返回的displayName函数就是闭包</span></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> myFunc = <span class="title function_">makeFunc</span>(); <span class="comment">//myFunc 是执行 makeFunc 时创建的 displayName 函数实例的引用</span></span><br><span class="line"><span class="title function_">myFunc</span>();</span><br></pre></td></tr></table></figure><p>注意:</p><ul><li>滥用闭包会导致内存泄露,处理方法:在退出函数之前,将不使用的局部变量全部删除。</li><li>闭包会在父函数外部,改变父函数内部变量的值。</li></ul><h3 id="闭包的用途"><a href="#闭包的用途" class="headerlink" title="闭包的用途"></a>闭包的用途</h3><p><strong>1. 封装</strong></p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> person = <span class="keyword">function</span>(<span class="params"></span>) {</span><br><span class="line"> <span class="keyword">var</span> name = <span class="string">"default"</span>; <span class="comment">//变量作用域为函数内部,外部无法访问</span></span><br><span class="line"> <span class="keyword">return</span> {</span><br><span class="line"> getName : <span class="keyword">function</span>(<span class="params"></span>) {</span><br><span class="line"> <span class="keyword">return</span> name;</span><br><span class="line"> },</span><br><span class="line"> setName : <span class="keyword">function</span>(<span class="params">newName</span>) {</span><br><span class="line"> name = newName;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line">}();</span><br><span class="line"></span><br><span class="line"><span class="title function_">print</span>(person.<span class="property">name</span>); <span class="comment">//直接访问,结果为undefined</span></span><br><span class="line"><span class="title function_">print</span>(person.<span class="title function_">getName</span>());</span><br><span class="line">person.<span class="title function_">setName</span>(<span class="string">"abruzzi"</span>);</span><br><span class="line"><span class="title function_">print</span>(person.<span class="title function_">getName</span>());</span><br><span class="line"></span><br><span class="line">得到结果如下:</span><br><span class="line"><span class="literal">undefined</span> </span><br><span class="line"><span class="keyword">default</span> </span><br><span class="line">abruzzi</span><br></pre></td></tr></table></figure><p><strong>2. 实现类和继承</strong></p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">Person</span>(<span class="params"></span>) {</span><br><span class="line"> <span class="keyword">var</span> name = <span class="string">"default"</span>;</span><br><span class="line"> <span class="keyword">return</span> {</span><br><span class="line"> getName : <span class="keyword">function</span>(<span class="params"></span>) {</span><br><span class="line"> <span class="keyword">return</span> name;</span><br><span class="line"> },</span><br><span class="line"> setName : <span class="keyword">function</span>(<span class="params">newName</span>) {</span><br><span class="line"> name = newName;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line">};</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> <span class="title class_">Jack</span> = <span class="keyword">function</span>(<span class="params"></span>){};</span><br><span class="line"><span class="title class_">Jack</span>.<span class="property"><span class="keyword">prototype</span></span> = <span class="keyword">new</span> <span class="title class_">Person</span>(); <span class="comment">//继承自Person</span></span><br><span class="line"><span class="title class_">Jack</span>.<span class="property"><span class="keyword">prototype</span></span>.<span class="property">Say</span> = <span class="keyword">function</span>(<span class="params"></span>) { <span class="comment">//添加私有方法</span></span><br><span class="line"> <span class="title function_">alert</span>(<span class="string">"Hello,my name is Jack"</span>);</span><br><span class="line">};</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> j = <span class="keyword">new</span> <span class="title class_">Jack</span>();</span><br><span class="line">j.<span class="title function_">setName</span>(<span class="string">"Jack"</span>);</span><br><span class="line"><span class="title function_">alert</span>(j.<span class="title function_">getName</span>());</span><br><span class="line">j.<span class="title class_">Say</span>();</span><br></pre></td></tr></table></figure><h2 id="JavaScript-继承"><a href="#JavaScript-继承" class="headerlink" title="JavaScript 继承"></a>JavaScript 继承</h2><ul><li>构造函数继承</li><li>原型链式继承</li><li>组合式继承(借用构造函数和原型链继承两种方式)</li><li>等等…</li></ul><h2 id="参考文档"><a href="#参考文档" class="headerlink" title="参考文档"></a>参考文档</h2><ul><li><a href="http://www.ruanyifeng.com/blog/2009/08/learning_javascript_closures.html">学习Javascript闭包-阮一峰</a></li><li><a href="http://www.cnblogs.com/yunfeifei/p/4019504.html">全面理解Javascript闭包和闭包的几种写法及用途</a></li><li><a href="http://www.ruanyifeng.com/blog/2010/05/object-oriented_javascript_encapsulation.html">Javascript 面向对象编程(一):封装-阮一峰</a></li><li><a href="http://www.ruanyifeng.com/blog/2010/05/object-oriented_javascript_inheritance.html">Javascript面向对象编程(二):构造函数的继承-阮一峰</a></li><li><a href="http://www.ruanyifeng.com/blog/2010/05/object-oriented_javascript_inheritance_continued.html">Javascript面向对象编程(三):非构造函数的继承-阮一峰</a></li><li><a href="https://www.imooc.com/article/20162">前端面试必备之JS继承方式总结</a></li><li><a href="https://www.cnblogs.com/humin/p/4556820.html">JS实现继承的几种方式</a></li></ul>]]></content>
<categories>
<category> 面试 </category>
</categories>
<tags>
<tag> 闭包 </tag>
<tag> 继承 </tag>
</tags>
</entry>
<entry>
<title>Vue生命周期</title>
<link href="/passages/Vue%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F/"/>
<url>/passages/Vue%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F/</url>
<content type="html"><![CDATA[<p>学习 <code>vue</code> 过程中, 生命周期是其中的一个很重要的概念,简单记录。</p><span id="more"></span><h2 id="Vue-官方供图"><a href="#Vue-官方供图" class="headerlink" title="Vue 官方供图"></a>Vue 官方供图</h2><p><img src="/images/vue-lifecycle.png"/></p><h2 id="钩子函数"><a href="#钩子函数" class="headerlink" title="钩子函数"></a>钩子函数</h2><p>创建=>挂载=>更新=>销毁</p><ul><li>beforeCreate</li><li>created</li><li>beforeMount</li><li>mounted</li><li>beforeUpdate</li><li>updated</li><li>beforeDestroy</li><li>destroyed</li></ul><h3 id="beforeCreate-前"><a href="#beforeCreate-前" class="headerlink" title="beforeCreate 前"></a>beforeCreate 前</h3><p>实例创建,执行 <code>init</code> 初始化。</p><h3 id="created-前"><a href="#created-前" class="headerlink" title="created 前"></a>created 前</h3><p>进行数据观测,事件初始化,在 <code>created</code> 之前数据已经绑定,但此时没有 el 选项。</p><p>主要应用:调用数据,调用方法,调用异步函数。</p><h3 id="beforeMount-前"><a href="#beforeMount-前" class="headerlink" title="beforeMount 前"></a>beforeMount 前</h3><p>在挂载开始之前被调用:相关的 render 函数(模板)首次被调用。</p><p>通过v-for生成的html还没有被挂载到页面上</p><h3 id="mounted-前"><a href="#mounted-前" class="headerlink" title="mounted 前"></a>mounted 前</h3><p><code>vue</code> 实例对象添加 <code>$el</code> 成员,并且替换掉DOM元素</p><h3 id="beforeUpdate-amp-amp-updated"><a href="#beforeUpdate-amp-amp-updated" class="headerlink" title="beforeUpdate && updated"></a>beforeUpdate && updated</h3><p>当 vue 发现 data 中的数据发生了改变,会触发对应组件的重新渲染,先后调用 <code>beforeUpdate</code> 和 <code>updated</code> 钩子函数.</p><h3 id="beforeDestroy-amp-amp-destroyed"><a href="#beforeDestroy-amp-amp-destroyed" class="headerlink" title="beforeDestroy && destroyed"></a>beforeDestroy && destroyed</h3><p><code>beforeDestroy</code> 钩子函数在实例销毁之前调用。在这一步,实例仍然完全可用。</p><p><code>destroyed</code>钩子函数在 Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。</p><h3 id="补充-mount"><a href="#补充-mount" class="headerlink" title="补充 $mount"></a>补充 $mount</h3><p>当 vue 没有挂载 el 时,我们可以用 $mount</p>]]></content>
<categories>
<category> Vue </category>
</categories>
<tags>
<tag> vue </tag>
<tag> 生命周期 </tag>
</tags>
</entry>
<entry>
<title>编程范式</title>
<link href="/passages/%E7%BC%96%E7%A8%8B%E6%96%B9%E5%BC%8F/"/>
<url>/passages/%E7%BC%96%E7%A8%8B%E6%96%B9%E5%BC%8F/</url>
<content type="html"><![CDATA[<p>日常学习工作中,经常会提到 <code>编程范式</code> , 面向对象编程, 面向过程编程, 函数式编程,响应式编程,等等,对这些内容简单记录</p><span id="more"></span><h2 id="面向过程编程"><a href="#面向过程编程" class="headerlink" title="面向过程编程"></a>面向过程编程</h2><p><code>面向过程</code> (Procedure Oriented) 是一种以过程为中心的编程思想。这些都是以什么正在发生为主要目标进行编程,不同于面向对象的是谁在受影响。与面向对象明显的不同就是封装、继承、类。</p><p>面向过程是具体的东西,是一种基础的方法,它考虑的是实际的实现, 而且面向过程是面向对象的基础。</p><p>典型代表: C</p><h2 id="面向对象编程"><a href="#面向对象编程" class="headerlink" title="面向对象编程"></a>面向对象编程</h2><p><code>面向对象程序设计</code> (Object Oriented Programming) 作为一种新方法,其本质是以建立模型体现出来的抽象思维过程和面向对象的方法。模型是用来反映现实世界中事物特征的。任何一个模型都不可能反映客观事物的一切具体特征,只能对事物特征和变化规律的一种抽象,且在它所涉及的范围内更普遍、更集中、更深刻地描述客体的特征。通过建立模型而达到的抽象是人们对客体认识的深化</p><p>面向对象的方法主要是把事物给对象化,包括其属性和行为。</p><p>典型代表: Java</p><h2 id="函数式编程"><a href="#函数式编程" class="headerlink" title="函数式编程"></a>函数式编程</h2><p><code>函数式编程</code> 是种编程方式,它将电脑运算视为函数的计算。函数编程语言最重要的基础是λ演算(lambda calculus),而且λ演算的函数可以接受函数当作输入(参数)和输出(返回值), 属于”结构化编程”的一种,主要思想是把运算过程尽量写成一系列嵌套的函数调用</p><p>和指令式编程相比,函数式编程强调函数的计算比指令的执行重要。</p><p>和过程化编程相比,函数式编程里函数的计算可随时调用。</p><p>函数式编程就是一种抽象程度很高的编程范式,纯粹的函数式编程语言编写的函数没有变量,因此,任意一个函数,只要输入是确定的,输出就是确定的,这种纯函数我们称之为没有副作用。而允许使用变量的程序设计语言,由于函数内部的变量状态不确定,同样的输入,可能得到不同的输出,因此,这种函数是有副作用的。</p><p>函数式编程的一个特点就是,允许把函数本身作为 <code>参数</code> 传入另一个函数,还允许 <code>返回一个函数</code></p><p>代表: scala python (不是纯函数式编程语言)</p><h2 id="响应式编程"><a href="#响应式编程" class="headerlink" title="响应式编程"></a>响应式编程</h2><p>简称RP(Reactive Programming)</p><p><code>响应式编程</code> 是一种面向数据流和变化传播的编程范式。这意味着可以在编程语言中很方便地表达静态或动态的数据流,而相关的计算模型会自动将变化的值通过数据流进行传播。</p><p>例如,在命令式编程环境中,a:=b+c表示将表达式的结果赋给a,而之后改变b或c的值不会影响a。但在响应式编程中,a的值会随着b或c的更新而更新。</p><p>电子表格程序就是响应式编程的一个例子。单元格可以包含字面值或类似”=B1+C1”的公式,而包含公式的单元格的值会依据其他单元格的值的变化而变化</p><h2 id="声明式编程"><a href="#声明式编程" class="headerlink" title="声明式编程"></a>声明式编程</h2><p>告诉机器你想要的是什么 <code>what</code>,让机器想出如何去做(how)</p><h2 id="命令式编程"><a href="#命令式编程" class="headerlink" title="命令式编程"></a>命令式编程</h2><p>命令机器如何去做事情 <code>how</code> ,这样不管你想要的是什么(what),它都会按照你的命令实现。</p><h2 id="面向切面编程"><a href="#面向切面编程" class="headerlink" title="面向切面编程"></a>面向切面编程</h2><p>Aspect Oriented Programming(AOP),面向切面编程。</p><p>AOP的编程,好像就是把我们在某个方面的功能提出来与一批对象进行隔离,这样与一批对象之间降低了耦合性,可以就某个功能进行编程。</p><p>AOP主要实现的目的是针对业务处理过程中的切面进行提取,它所面对的是处理过程中的某个步骤或阶段,以获得逻辑过程中各部分之间低耦合性的隔离效果</p><h2 id="参考"><a href="#参考" class="headerlink" title="参考"></a>参考</h2><ul><li><a href="https://www.liaoxuefeng.com/wiki/001374738125095c955c1e6d8bb493182103fac9270762a000/001386819866394c3f9efcd1a454b2a8c57933e976445c0000">函数式编程-廖雪峰</a></li></ul>]]></content>
<categories>
<category> 编程范式 </category>
</categories>
<tags>
<tag> 编程范式 </tag>
</tags>
</entry>
<entry>
<title>页面可视化工具 Pipeline 本地搭建</title>
<link href="/passages/%E9%A1%B5%E9%9D%A2%E5%8F%AF%E8%A7%86%E5%8C%96%E5%B7%A5%E5%85%B7Pipeline%E6%90%AD%E5%BB%BA/"/>
<url>/passages/%E9%A1%B5%E9%9D%A2%E5%8F%AF%E8%A7%86%E5%8C%96%E5%B7%A5%E5%85%B7Pipeline%E6%90%AD%E5%BB%BA/</url>
<content type="html"><![CDATA[<p><code>pipeline</code> 是开源的页面可视化搭建框架, 基于 <code>pipeline</code> 可以快速开发出满足运营活动需要的页面可视化搭建系统.本文档主要记录部署过程的问题.</p><span id="more"></span><h2 id="Pipeline-本地部署"><a href="#Pipeline-本地部署" class="headerlink" title="Pipeline 本地部署"></a>Pipeline 本地部署</h2><p><a href="https://github.com/page-pipepline/pipeline-document/wiki/Pipeline-%E6%9C%AC%E5%9C%B0%E9%83%A8%E7%BD%B2">Pipeline 本地部署教程</a></p><p>按照上述教程进行部署即可:</p><p>对应目录结构:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">/Users/pipeline //本地新建工作目录</span><br><span class="line">├── pipeline-editor // 可视化编辑器. git clone</span><br><span class="line">├── pipeline-mongo // 后台数据库, git clone</span><br><span class="line">├── pipeline-node-server // node后台, git clone</span><br><span class="line">├── pipeline-resources // 项目资源 ,新建</span><br><span class="line">├── pipeline-template // vue 模板库, git clone</span><br><span class="line">└── pipeline-template-react // react 模板库, git clone</span><br></pre></td></tr></table></figure><p>主要步骤如下:</p><ul><li>建立本地文件夹,工作目录</li><li>clone 工程源码</li><li>生成页面模板, <code>vue 模板</code> 及 <code>react 模板</code></li><li>配置数据库, <code>docker-compose</code>, <code>mongoDB</code></li><li>启动 node 服务</li><li>启动编辑器</li><li>Hello pipeline</li></ul><p>主要困难点: <code>配置数据库</code></p><p>上述各个模块依赖关系:</p><p><img src="/images/post/pipeline.png" alt="image"></p><h2 id="安装记录"><a href="#安装记录" class="headerlink" title="安装记录"></a>安装记录</h2><p>此模块只记录 <code>配置数据库</code> 模块,其它模块按照教程一直执行就行(node环境必须)</p><h3 id="下载对应工具-Docker-Desktop-Windows"><a href="#下载对应工具-Docker-Desktop-Windows" class="headerlink" title="下载对应工具 Docker Desktop (Windows)"></a>下载对应工具 <code>Docker Desktop (Windows)</code></h3><p>注:下载的 <code>Docker for Windows Installer.exe</code> 点击安装一直没有反应,应该是当前系统不支持。</p><h3 id="下载对应工具-Docker-Toolbox-for-Windows"><a href="#下载对应工具-Docker-Toolbox-for-Windows" class="headerlink" title="下载对应工具 Docker Toolbox for Windows"></a>下载对应工具 <code>Docker Toolbox for Windows</code></h3><ul><li>点击 <code>DockerToolbox.exe</code> 进行安装。</li><li>安装后效果如下:<img src="/images/post/pipeline1.png" alt="image"></li><li>双击 <code>Docker Quickstart Terminal</code> 的快捷方式, 出现 快捷方式问题。<img src="/images/post/pipeline2.png" alt="image"></li><li>右键快捷方式,点击属性,选择目标,修改对应 git 路径 <figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">"C:\Program Files\Git\bin\bash.exe" --login -i "C:\Program Files\Docker Toolbox\start.sh" 修改如下:</span><br><span class="line">"G:\Nodejs\git-bash\Git\bin\bash.exe" --login -i "C:\Program Files\Docker Toolbox\start.sh"</span><br></pre></td></tr></table></figure></li><li><p>继续右键快捷方式,提示 Looking for vboxmanage.exe,查资料,是没有配置环境变量的原因,可通过配置环境变量或者点击 <code>start.sh</code> 正常启动。</p></li><li><p>点击 <code>start.sh</code> 启动时,发现拉取文件错误,<code>boot2docker.iso</code>, 到<a href="https://github.com/boot2docker/boot2docker/releases">对应链接</a>手动下载放置指定目录,按照提示的目录放置即可</p></li><li><p>最终效果:<br><img src="/images/post/pipeline3.png" alt="image"></p></li><li><p>数据库启动结果:</p></li></ul><p><img src="/images/post/pipeline4.png" alt="image"></p><ul><li>后端工程启动结果:</li></ul><p><img src="/images/post/pipeline5.png" alt="image"></p><p>数据库启动正常,但是仍然 <code>连不上数据库</code> ,不知道原因!!!!</p><h3 id="相关链接"><a href="#相关链接" class="headerlink" title="相关链接"></a>相关链接</h3><ul><li><a href="https://docs.docker.com/compose/install/">docker-compose 安装教程-官方</a></li><li><a href="https://www.cnblogs.com/stulzq/p/7743667.html">Windows 10 安装 Docker for Windows</a></li><li><a href="https://docs.docker.com/toolbox/toolbox_install_windows/">Install Docker Toolbox on Windows</a></li><li><a href="https://cloud.tencent.com/developer/article/1354117">点击Docker Quickstart Terminal出现Windows正在查找bash.exe的解决方法</a></li><li><a href="https://www.imooc.com/qadetail/212770?lastmedia=1">“Docker Quickstart Terminal”启动错误!找不到vboxmanage.exe</a></li><li><a href="https://blog.csdn.net/csdn_duomaomao/article/details/73028390">旧版本的Docker Toolbox 无法正常运行的解决办法, boot2docker.iso</a></li></ul>]]></content>
<categories>
<category> 工程部署 </category>
</categories>
<tags>
<tag> 页面可视化 </tag>
<tag> Pipeline </tag>
<tag> web 编辑器 </tag>
</tags>
</entry>
<entry>
<title>【置顶】hexo博客配置各种小功能</title>
<link href="/passages/hexo%E5%8D%9A%E5%AE%A2%E9%85%8D%E7%BD%AE%E5%90%84%E7%A7%8D%E5%B0%8F%E5%8A%9F%E8%83%BD/"/>
<url>/passages/hexo%E5%8D%9A%E5%AE%A2%E9%85%8D%E7%BD%AE%E5%90%84%E7%A7%8D%E5%B0%8F%E5%8A%9F%E8%83%BD/</url>
<content type="html"><![CDATA[<p>使用 <code>hexo</code> 搭建博客且主题配置后,是否想让自己的博客更加精致那?例如:评论功能,文章字数统计和阅读时长,图片预览,鼠标点击效果,添加可爱的二次元,音乐播放,RSS, 分享, 浏览量统计,站内搜索,置顶,标签云,一键分享,Fork me on Github, 等等,本文主要记录此模块内容。</p><span id="more"></span><h2 id="添加字数统计与阅读时长"><a href="#添加字数统计与阅读时长" class="headerlink" title="添加字数统计与阅读时长"></a>添加字数统计与阅读时长</h2><p>npm install <a href="https://github.com/willin/hexo-wordcount">hexo-wordcount</a> –save</p><p>新建 <code>word.ejs</code></p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span></span><br><span class="line"> <i class="fa fa-keyboard-o"></i> &nbsp;字数统计 : <%= wordcount(page.content) %> 字</span><br><span class="line"></span></span><br><span class="line"></span><br><span class="line"><span></span><br><span class="line"> <i class="fa fa-hourglass-half"></i> &nbsp;阅读时长 : <%= min2read(page.content) %> 分</span><br><span class="line"></span></span><br></pre></td></tr></table></figure><p>对应页面内容处添加判断, <code>word_count</code> 标志是否开启字数与阅读时长显示。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><% if(theme.word_count) { %></span><br><span class="line"> <%- partial("_partial/word.ejs") %></span><br><span class="line"><% } %></span><br></pre></td></tr></table></figure><p>具体效果:<br><img src="/images/post/word.png" alt=""></p><p>其中字体图标采用 <a href="http://www.fontawesome.com.cn/faicons/">fontawesome</a>, 引用css即可使用</p><h2 id="添加评论"><a href="#添加评论" class="headerlink" title="添加评论"></a>添加评论</h2><p><a href="https://github.com/gitalk/gitalk/blob/master/readme-cn.md">gitalk</a> 和 <code>github issues</code> 挂钩的插件, 简单易配置</p><p>具体效果:<br><img src="/images/post/gitalk.png" alt=""></p><h2 id="照片预览"><a href="#照片预览" class="headerlink" title="照片预览"></a>照片预览</h2><p><a href="https://github.com/fancyapps/fancybox">fancybox</a> , 使用简单,点击图片即可大图预览。</p><h2 id="鼠标点击效果"><a href="#鼠标点击效果" class="headerlink" title="鼠标点击效果"></a>鼠标点击效果</h2><p>创建 <code>clicklove.js</code> 文件</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">!<span class="keyword">function</span>(<span class="params">e,t,a</span>){<span class="keyword">function</span> <span class="title function_">n</span>(<span class="params"></span>){<span class="title function_">c</span>(<span class="string">".heart{width: 10px;height: 10px;position: fixed;background: #f00;transform: rotate(45deg);-webkit-transform: rotate(45deg);-moz-transform: rotate(45deg);}.heart:after,.heart:before{content: '';width: inherit;height: inherit;background: inherit;border-radius: 50%;-webkit-border-radius: 50%;-moz-border-radius: 50%;position: fixed;}.heart:after{top: -5px;}.heart:before{left: -5px;}"</span>),<span class="title function_">o</span>(),<span class="title function_">r</span>()}<span class="keyword">function</span> <span class="title function_">r</span>(<span class="params"></span>){<span class="keyword">for</span>(<span class="keyword">var</span> e=<span class="number">0</span>;e<d.<span class="property">length</span>;e++)d[e].<span class="property">alpha</span><=<span class="number">0</span>?(t.<span class="property">body</span>.<span class="title function_">removeChild</span>(d[e].<span class="property">el</span>),d.<span class="title function_">splice</span>(e,<span class="number">1</span>)):(d[e].<span class="property">y</span>--,d[e].<span class="property">scale</span>+=<span class="number">.004</span>,d[e].<span class="property">alpha</span>-=<span class="number">.013</span>,d[e].<span class="property">el</span>.<span class="property">style</span>.<span class="property">cssText</span>=<span class="string">"left:"</span>+d[e].<span class="property">x</span>+<span class="string">"px;top:"</span>+d[e].<span class="property">y</span>+<span class="string">"px;opacity:"</span>+d[e].<span class="property">alpha</span>+<span class="string">";transform:scale("</span>+d[e].<span class="property">scale</span>+<span class="string">","</span>+d[e].<span class="property">scale</span>+<span class="string">") rotate(45deg);background:"</span>+d[e].<span class="property">color</span>+<span class="string">";z-index:99999"</span>);<span class="title function_">requestAnimationFrame</span>(r)}<span class="keyword">function</span> <span class="title function_">o</span>(<span class="params"></span>){<span class="keyword">var</span> t=<span class="string">"function"</span>==<span class="keyword">typeof</span> e.<span class="property">onclick</span>&&e.<span class="property">onclick</span>;e.<span class="property">onclick</span>=<span class="keyword">function</span>(<span class="params">e</span>){t&&<span class="title function_">t</span>(),<span class="title function_">i</span>(e)}}<span class="keyword">function</span> <span class="title function_">i</span>(<span class="params">e</span>){<span class="keyword">var</span> a=t.<span class="title function_">createElement</span>(<span class="string">"div"</span>);a.<span class="property">className</span>=<span class="string">"heart"</span>,d.<span class="title function_">push</span>({<span class="attr">el</span>:a,<span class="attr">x</span>:e.<span class="property">clientX</span>-<span class="number">5</span>,<span class="attr">y</span>:e.<span class="property">clientY</span>-<span class="number">5</span>,<span class="attr">scale</span>:<span class="number">1</span>,<span class="attr">alpha</span>:<span class="number">1</span>,<span class="attr">color</span>:<span class="title function_">s</span>()}),t.<span class="property">body</span>.<span class="title function_">appendChild</span>(a)}<span class="keyword">function</span> <span class="title function_">c</span>(<span class="params">e</span>){<span class="keyword">var</span> a=t.<span class="title function_">createElement</span>(<span class="string">"style"</span>);a.<span class="property">type</span>=<span class="string">"text/css"</span>;<span class="keyword">try</span>{a.<span class="title function_">appendChild</span>(t.<span class="title function_">createTextNode</span>(e))}<span class="keyword">catch</span>(t){a.<span class="property">styleSheet</span>.<span class="property">cssText</span>=e}t.<span class="title function_">getElementsByTagName</span>(<span class="string">"head"</span>)[<span class="number">0</span>].<span class="title function_">appendChild</span>(a)}<span class="keyword">function</span> <span class="title function_">s</span>(<span class="params"></span>){<span class="keyword">return</span><span class="string">"rgb("</span>+~~(<span class="number">255</span>*<span class="title class_">Math</span>.<span class="title function_">random</span>())+<span class="string">","</span>+~~(<span class="number">255</span>*<span class="title class_">Math</span>.<span class="title function_">random</span>())+<span class="string">","</span>+~~(<span class="number">255</span>*<span class="title class_">Math</span>.<span class="title function_">random</span>())+<span class="string">")"</span>}<span class="keyword">var</span> d=[];e.<span class="property">requestAnimationFrame</span>=<span class="keyword">function</span>(<span class="params"></span>){<span class="keyword">return</span> e.<span class="property">requestAnimationFrame</span>||e.<span class="property">webkitRequestAnimationFrame</span>||e.<span class="property">mozRequestAnimationFrame</span>||e.<span class="property">oRequestAnimationFrame</span>||e.<span class="property">msRequestAnimationFrame</span>||<span class="keyword">function</span>(<span class="params">e</span>){<span class="built_in">setTimeout</span>(e,<span class="number">1e3</span>/<span class="number">60</span>)}}(),<span class="title function_">n</span>()}(<span class="variable language_">window</span>,<span class="variable language_">document</span>);</span><br><span class="line"></span><br></pre></td></tr></table></figure><p>引入对应 <code>js</code> 即可, 页面点击即可看到 ♥ 效果。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><%- js(['js/clicklove.js'])%></span><br></pre></td></tr></table></figure><h2 id="添加网站二次元模型"><a href="#添加网站二次元模型" class="headerlink" title="添加网站二次元模型"></a>添加网站二次元模型</h2><p>npm install –save <a href="https://github.com/EYHN/hexo-helper-live2d/blob/master/README.zh-CN.md">hexo-helper-live2d</a></p><p>根目录下 <code>_config.yaml</code> 添加配置。</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">live2d:</span></span><br><span class="line"> <span class="attr">enable:</span> <span class="literal">true</span></span><br><span class="line"> <span class="attr">scriptFrom:</span> <span class="string">local</span></span><br><span class="line"> <span class="attr">model:</span></span><br><span class="line"> <span class="attr">use:</span> <span class="string">live2d-widget-model-wanko</span></span><br><span class="line"> <span class="attr">display:</span></span><br><span class="line"> <span class="attr">position:</span> <span class="string">right</span></span><br><span class="line"> <span class="attr">width:</span> <span class="number">150</span></span><br><span class="line"> <span class="attr">height:</span> <span class="number">250</span></span><br><span class="line"> <span class="attr">mobile:</span></span><br><span class="line"> <span class="attr">show:</span> <span class="literal">true</span> </span><br></pre></td></tr></table></figure><p>更多模型,安装对应模块即可。<a href="https://github.com/xiazeyu/live2d-widget-models">live2d-widget-models</a></p><h2 id="音乐播放器"><a href="#音乐播放器" class="headerlink" title="音乐播放器"></a>音乐播放器</h2><ul><li><a href="https://music.163.com/#/song?id=487520041">网易云外链播放器</a></li></ul><p>效果如下:<img src="/images/post/music.png" alt=""></p><ul><li><a href="https://aplayer.js.org/#/">aplayer</a>,<a href="https://aplayer.js.org/#/zh-Hans/">中文文档</a></li></ul><p>效果如下:<img src="/images/post/music2.png" alt=""></p><h2 id="RSS订阅"><a href="#RSS订阅" class="headerlink" title="RSS订阅"></a>RSS订阅</h2><p>npm install <a href="https://github.com/hexojs/hexo-generator-feed">hexo-generator-feed</a> –save</p><p>根目录下 <code>_config.yaml</code> 添加配置。</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># RSS订阅</span></span><br><span class="line"><span class="attr">plugin:</span></span><br><span class="line"> <span class="string">hexo-generator-feed</span></span><br><span class="line"><span class="comment">#Feed Atom</span></span><br><span class="line"><span class="attr">feed:</span></span><br><span class="line"> <span class="attr">type:</span> <span class="string">atom</span></span><br><span class="line"> <span class="attr">path:</span> <span class="string">atom.xml</span></span><br><span class="line"> <span class="attr">limit:</span> <span class="number">20</span></span><br></pre></td></tr></table></figure><p>主题目录下的 <code>_config.yml</code> 文件,设置 RSS 地址:</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># RSS文件位置</span></span><br><span class="line"><span class="attr">rss:</span> <span class="string">/atom.xml</span></span><br></pre></td></tr></table></figure><p>页面添加图标展示</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><a href="<%- url_for(theme.rss) %>" title="<%= __('rss_feed') %>"></span><br><span class="line"> <i class="fa fa-rss-square"></i></span><br><span class="line"></a></span><br></pre></td></tr></table></figure><h2 id="网站运行时间-amp-amp-总字数"><a href="#网站运行时间-amp-amp-总字数" class="headerlink" title="网站运行时间 && 总字数"></a>网站运行时间 && 总字数</h2><p>写个 <code>js</code> 脚本运行即可,计算时间</p><p>网站总字数在 <code>添加字数统计与阅读时长</code> 介绍时对应插件提供此功能。</p><h2 id="一键分享"><a href="#一键分享" class="headerlink" title="一键分享"></a>一键分享</h2><p><a href="https://github.com/overtrue/share.js">一键分享</a> , 简单易用,直接引用配置即可。</p><h2 id="返回顶部"><a href="#返回顶部" class="headerlink" title="返回顶部"></a>返回顶部</h2><p><a href="https://www.tuicool.com/articles/nArEni">Hexo 博客功能扩展 - 添加回滚到顶部按钮</a></p><h2 id="浏览量"><a href="#浏览量" class="headerlink" title="浏览量"></a>浏览量</h2><p>此处不做说明,需要注册提供统计功能的服务, 注册后直接使用即可。网上很多服务提供者有对应功能。<br>百度统计,谷歌统计,不蒜子统计,cnzz, leancloud 等等。</p><p><del>本站采用的为 <a href="https://valine.js.org/">Valine一款基于Leancloud的快速、简洁且高效的无后端评论系统</a>, 只用了其中的<code>文章阅读量统计</code>模块,评论系统采用的 <code>gitalk</code>, 原因是当时配置完评论系统后发现无法及时的接受通知,博主和评论者无法及时互联,发邮件有限制。所以切换了评论插件。不过后续发现 <a href="https://github.com/DesertsP/Valine-Admin">Valine-Admin-Valine评论系统的扩展和增强</a> 实现评论邮件通知、评论管理、垃圾评论过滤等功能。可以对其进行修改增强即可。</del></p><p><del>具体 <code>Valine</code> 如何配置,详情参考的为 <a href="https://godbmw.com/passages/2018-11-15-theme-bmw-docs-zh/#4.%20%E8%AF%84%E8%AE%BA%E7%B3%BB%E7%BB%9F%20&&%20%E6%96%87%E7%AB%A0%E7%BB%9F%E8%AE%A1">Theme-BMW 中文文档, 本站博客主题</a>,前人栽树后人乘凉,O(∩_∩)O哈哈~, 如果为其它主题,参考 Valine 官网即可。</del></p><p>本站统计 20190312 已修改为不蒜子统计,统计数量已重置。</p><h2 id="SEO"><a href="#SEO" class="headerlink" title="SEO"></a>SEO</h2><p>可以向各个搜索引擎提交自己的网站</p><ul><li><a href="https://ziyuan.baidu.com/linksubmit/url">百度入口</a></li><li><a href="https://www.google.com/webmasters/tools/submit-url?pli=1">谷歌入口</a></li><li><a href="http://info.so.360.cn/site_submit.html">360入口</a></li><li><a href="http://fankui.help.sogou.com/index.php/web/web/index?type=4">搜狗入口</a></li><li><a href="https://blogs.bing.com/webmaster/september-2018/Anonymous-URL-Submission-Tool-Being-Retired">必应入口</a></li></ul><h2 id="文章置顶"><a href="#文章置顶" class="headerlink" title="文章置顶"></a>文章置顶</h2><p>npm install <a href="https://github.com/amlove2/hexo-generator-topindex">hexo-generator-topindex</a> –save</p><p>设置 <code>top</code> 参数, 值越大,优先级越高</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">---</span></span><br><span class="line"><span class="attr">title:</span> <span class="string">Hello</span> <span class="string">World</span></span><br><span class="line"><span class="attr">date:</span> <span class="number">2017-03-12 19:45:02</span></span><br><span class="line"><span class="attr">top:</span> <span class="number">5</span></span><br><span class="line"><span class="meta">---</span></span><br></pre></td></tr></table></figure><h2 id="标签云"><a href="#标签云" class="headerlink" title="标签云"></a>标签云</h2><p>页面添加元素代码如下:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><div class="tags"></span><br><span class="line"> <%- tagcloud({</span><br><span class="line"> min_font: 16,</span><br><span class="line"> max_font: 35,</span><br><span class="line"> amount: 999,</span><br><span class="line"> color: true,</span><br><span class="line"> start_color: 'gray',</span><br><span class="line"> end_color: 'black',</span><br><span class="line"> }) %></span><br><span class="line"></div></span><br></pre></td></tr></table></figure><p>对应可添加样式代码如下:</p><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><style></span><br><span class="line"> <span class="selector-class">.tags</span> {</span><br><span class="line"> <span class="attribute">max-width</span>: <span class="number">60em</span>;</span><br><span class="line"> <span class="attribute">margin</span>: <span class="number">2em</span> auto;</span><br><span class="line"> <span class="attribute">margin-top</span>: <span class="number">0em</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="selector-class">.tags</span> <span class="selector-tag">a</span> {</span><br><span class="line"> <span class="attribute">margin-right</span>: <span class="number">1em</span>;</span><br><span class="line"> <span class="attribute">line-height</span>: <span class="number">65px</span>;</span><br><span class="line"> <span class="attribute">border-bottom</span>: <span class="number">1px</span> solid gray;</span><br><span class="line"> <span class="attribute">white-space</span>: nowrap;</span><br><span class="line"> <span class="attribute">transition</span>: border-bottom .<span class="number">5s</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="selector-class">.tags</span> <span class="selector-tag">a</span><span class="selector-pseudo">:hover</span> {</span><br><span class="line"> <span class="attribute">border-bottom</span>: <span class="number">3px</span> dotted gray;</span><br><span class="line"> <span class="attribute">text-decoration</span>: none;</span><br><span class="line"> }</span><br><span class="line"></style></span><br></pre></td></tr></table></figure><h2 id="站内搜素"><a href="#站内搜素" class="headerlink" title="站内搜素"></a>站内搜素</h2><p>npm install <a href="https://github.com/wzpan/hexo-generator-search">hexo-generator-search</a> –save</p><p>根目录 <code>_config.yml</code> 配置</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">## 站内搜索相关配置</span></span><br><span class="line"><span class="attr">search:</span></span><br><span class="line"> <span class="attr">enable:</span> <span class="literal">true</span></span><br><span class="line"> <span class="attr">path:</span> <span class="string">search.xml</span></span><br><span class="line"> <span class="attr">field:</span> <span class="string">post</span></span><br><span class="line"> <span class="attr">content:</span> <span class="literal">true</span></span><br></pre></td></tr></table></figure><ul><li>写一个<a href="https://github.com/wzpan/hexo-theme-freemind/blob/master/layout/_widget/search.ejs#L8">搜索视图</a></li><li>write a <a href="https://github.com/wzpan/hexo-theme-freemind/blob/master/source/js/search.js">search script</a></li><li>tell hexo to <a href="https://github.com/wzpan/hexo-theme-freemind/blob/master/layout/_partial/after_footer.ejs#L22">connect the above two part</a></li></ul><ol><li>引入 jquery 和上述 搜索脚本</li><li>页面放入搜索图标,点击出现搜索视图,即搜索弹层</li><li>对应弹层逻辑编写即可</li></ol><h2 id="文章加密"><a href="#文章加密" class="headerlink" title="文章加密"></a>文章加密</h2><p><code>展示文章</code> 对应的 <code>ejs</code> 文件头部加入:</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><script></span><br><span class="line"> (<span class="keyword">function</span>(<span class="params"></span>){</span><br><span class="line"> <span class="keyword">if</span>(<span class="string">'<%- page.password %>'</span> !== <span class="string">""</span>){</span><br><span class="line"> <span class="keyword">if</span> (<span class="title function_">prompt</span>(<span class="string">'请输入文章密码'</span>) !== <span class="string">'<%- page.password %>'</span>) {</span><br><span class="line"> <span class="title function_">alert</span>(<span class="string">'密码错误!'</span>);</span><br><span class="line"> history.<span class="title function_">back</span>();</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> })();</span><br><span class="line"></script></span><br></pre></td></tr></table></figure><p>文章的 <code>md</code> 源文件,头部增加配置 <code>password</code>, 即可实现</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">title:</span> <span class="string">【置顶】hexo博客配置各种小功能</span></span><br><span class="line"><span class="attr">date:</span> <span class="number">2019-01-20 16:40:00</span></span><br><span class="line"><span class="attr">password:</span> <span class="number">12345</span></span><br></pre></td></tr></table></figure><p>对应效果: <img src="/images/post/密码.png" alt=""></p><h2 id="Fork-me-on-Github"><a href="#Fork-me-on-Github" class="headerlink" title="Fork me on Github"></a>Fork me on Github</h2><p><a href="https://github.blog/2008-12-19-github-ribbons/">GitHub Ribbons</a> 按照 <code>Github</code> 官方提供的代码粘贴到页面上即可,记得把 <code>a链接</code> 改为自己的Github地址.</p><p>如果展示位置不对,可添加样式修正</p><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="attribute">position</span>: fixed;</span><br><span class="line"><span class="attribute">right</span>: <span class="number">0</span>;</span><br><span class="line"><span class="attribute">top</span>: <span class="number">0</span>;</span><br><span class="line"><span class="attribute">z-index</span>: <span class="number">1000</span></span><br></pre></td></tr></table></figure><p>如果以上方式图片无法访问,推荐 <a href="https://github.com/tholman/github-corners">github-corners</a>, 按照示例使用即可。</p><h2 id="动态背景"><a href="#动态背景" class="headerlink" title="动态背景"></a>动态背景</h2><p>根目录 <code>_config.yml</code> 配置</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># background settings</span></span><br><span class="line"><span class="comment"># add canvas-nest effect</span></span><br><span class="line"><span class="comment"># see detail from https://github.com/hustcc/canvas-nest.js</span></span><br><span class="line"><span class="attr">canvas_nest:</span> <span class="literal">true</span> </span><br></pre></td></tr></table></figure><p><code></body></code> 标签前加入下面代码:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><% if (config.canvas_nest) { %></span><br><span class="line"> <script type="text/javascript"</span><br><span class="line"> color="0,0,255" opacity='0.7' zIndex="1" count="99" src="//cdn.bootcss.com/canvas-nest.js/1.0.0/canvas-nest.min.js"></script></span><br><span class="line"><% } %></span><br></pre></td></tr></table></figure><p>注意:需要处理好动态背景和页面模块的 <code>z-index</code> 的值,不然有时不显示动态背景,有时页面内容无法点击。</p><p>页面内容 <code>z-index</code> 值偏大,但是需要设置页面内容宽度。</p><h2 id="留言板"><a href="#留言板" class="headerlink" title="留言板"></a>留言板</h2><p>生成留言板页面:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ hexo new page messageBoard</span><br></pre></td></tr></table></figure><p>修改留言板页面的 <code>markdown</code> 文件(文件路径:your-blog/source/messageBoard/index.md)的内容:</p><figure class="highlight md"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">---</span><br><span class="line">title: messageBoard</span><br><span class="line">date: <!-- 自动生成,无需修改 --></span><br><span class="line"><span class="section">type: "messageBoard"</span></span><br><span class="line"><span class="section">---</span></span><br><span class="line"></span><br><span class="line"><span class="section">## 留言板</span></span><br></pre></td></tr></table></figure><p>查看留言板页面:浏览器中打开 <a href="http://localhost:4000/messageBoard/">http://localhost:4000/messageBoard/</a></p><p>注:type字段的值是 <code>messageBoard</code></p><p>增加对此页面的解析处理:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><% if(page.type === "messageBoard"){ %></span><br><span class="line"> <div></span><br><span class="line"> <%- page.content %></span><br><span class="line"> </div></span><br><span class="line"> <% if(theme.gitalk.comment){ %></span><br><span class="line"> <%- partial("_partial/gitalk") %></span><br><span class="line"> <% } %></span><br><span class="line"><% } %></span><br></pre></td></tr></table></figure>]]></content>
<categories>
<category> 博客搭建 </category>
</categories>
<tags>
<tag> hexo </tag>
<tag> hexo-功能配置 </tag>
</tags>
</entry>
<entry>
<title>k8s 命令备忘</title>
<link href="/passages/k8s%E5%91%BD%E4%BB%A4%E5%A4%87%E5%BF%98/"/>
<url>/passages/k8s%E5%91%BD%E4%BB%A4%E5%A4%87%E5%BF%98/</url>
<content type="html"><![CDATA[<p><code>k8s</code> 命令备忘</p><span id="more"></span><h2 id="kubectl"><a href="#kubectl" class="headerlink" title="kubectl"></a>kubectl</h2><blockquote><p><code>kubectl</code> 用于运行 <code>Kubernetes</code> 集群命令的管理工具</p></blockquote><h2 id="语法"><a href="#语法" class="headerlink" title="语法"></a>语法</h2><blockquote><p>kubectl [command] [TYPE] [NAME] [flags]</p></blockquote><ul><li>command:指定要在一个或多个资源执行的操作,例如操作 create,get,describe,delete。</li><li>TYPE:指定资源类型 Resource types。Resource types会区分大小写,也可以指定单数,复数或缩写的形式。</li><li>NAME:指定 Resource 的 Name。Name区分大小写,如果省略Name,则显示所有资源的详细信息</li><li>flags:指定可选flags。例如,你可以使用-s 或 –server flag来指定 Kubernetes API Server 的地址和端口。提示:命令行指定的flags将覆盖默认值和任何相应的环境变量。</li></ul><h2 id="常用命令表"><a href="#常用命令表" class="headerlink" title="常用命令表"></a>常用命令表</h2><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br></pre></td><td class="code"><pre><span class="line"><span class="section"># 通过配置文件名创建一个集群资源对象, 支持JSON和YAML格式的文件</span></span><br><span class="line">kubectl create -f FILENAME</span><br><span class="line"></span><br><span class="line"><span class="section"># 对文件或stdin的资源进行配置更改。</span></span><br><span class="line">kubectl apply -f FILENAME</span><br><span class="line"></span><br><span class="line"><span class="section"># 根据配置文件、目录或指定的literal-value创建configmap</span></span><br><span class="line">kubectl create configmap NAME [--from-file=[key=]source] [--from-literal=key1=value1] [--dry-run]</span><br><span class="line">kubectl create configmap my-config --from-file=path/to/bar</span><br><span class="line"></span><br><span class="line"><span class="section"># 创建一个具有指定名称的namespace</span></span><br><span class="line">kubectl create namespace NAME [--dry-run]</span><br><span class="line">kubectl create namespace my-namespace</span><br><span class="line"></span><br><span class="line"><span class="section"># 通过配置文件名、stdin、资源名称或label选择器来删除资源。</span></span><br><span class="line">kubectl delete ([-f FILENAME] | TYPE [(NAME | -l label | --all)])</span><br><span class="line">kubectl delete -f ./pod.json</span><br><span class="line">kubectl delete pod,service baz foo</span><br><span class="line">kubectl delete po <span class="language-xml"><span class="tag"><<span class="name">podname</span>></span></span> -n namespace</span><br><span class="line"></span><br><span class="line"><span class="section"># 获取列出一个或多个资源的信息。</span></span><br><span class="line">kubectl get po</span><br><span class="line">kubectl get rc,services</span><br><span class="line"></span><br><span class="line"><span class="section"># 显示一个或多个resources的详细状态</span></span><br><span class="line">kubectl describe (-f FILENAME | TYPE [NAME<span class="emphasis">_PREFIX | /NAME | -l label]) [flags]</span></span><br><span class="line"><span class="emphasis">kubectl describe <span class="language-xml"><span class="tag"><<span class="name">podname</span>></span></span> bash -n namespace</span></span><br><span class="line"><span class="emphasis"></span></span><br><span class="line"><span class="emphasis"># 对pod中的容器执行命令</span></span><br><span class="line"><span class="emphasis"># Get a shell to the running Container</span></span><br><span class="line"><span class="emphasis">kubectl exec POD [-c CONTAINER] [-i] [-t] [flags] [-- COMMAND [args...]]</span></span><br><span class="line"><span class="emphasis">kubectl exec -it <span class="language-xml"><span class="tag"><<span class="name">podname</span>></span></span> bash -n namespace</span></span><br><span class="line"><span class="emphasis"></span></span><br><span class="line"><span class="emphasis"># 输出pod中一个容器的日志</span></span><br><span class="line"><span class="emphasis">kubectl logs [-f] [-p] POD [-c CONTAINER]</span></span><br><span class="line"><span class="emphasis">kubectl logs <span class="language-xml"><span class="tag"><<span class="name">podname</span>></span></span> bash -n namespace</span></span><br></pre></td></tr></table></figure><h2 id="参考"><a href="#参考" class="headerlink" title="参考"></a>参考</h2><ul><li><a href="http://docs.kubernetes.org.cn/">Kubernetes中文社区 | 中文文档</a></li><li><a href="https://www.kubernetes.org.cn/docs">Kubernetes中文手册</a></li></ul>]]></content>
<categories>
<category> 工程部署 </category>
</categories>
<tags>
<tag> k8s </tag>
<tag> kubectl </tag>
</tags>
</entry>
<entry>
<title>k8s 各模块关系</title>
<link href="/passages/k8s%E5%90%84%E6%A8%A1%E5%9D%97%E5%85%B3%E7%B3%BB/"/>
<url>/passages/k8s%E5%90%84%E6%A8%A1%E5%9D%97%E5%85%B3%E7%B3%BB/</url>
<content type="html"><![CDATA[<p>简单介绍 <code>k8s</code> 各模块关系</p><span id="more"></span><h2 id="关与-Kubernetes"><a href="#关与-Kubernetes" class="headerlink" title="关与 Kubernetes"></a>关与 <strong>Kubernetes</strong></h2><blockquote><p><code>Kubernetes</code> 是容器集群管理系统,是一个开源的平台,可以实现容器集群的自动化部署、自动扩缩容、维护等功能。<br><code>Kubernetes</code> 的名字来自希腊语,意思是“舵手” 或 “领航员”。K8s是将8个字母“ubernete”替换为“8”的缩写。</p></blockquote><h2 id="各模块关系图"><a href="#各模块关系图" class="headerlink" title="各模块关系图"></a>各模块关系图</h2><p><img src="/images/k8s.png"/></p><h2 id="Kubernetes-Pod-概述"><a href="#Kubernetes-Pod-概述" class="headerlink" title="Kubernetes Pod 概述"></a><strong>Kubernetes Pod</strong> 概述</h2><blockquote><p><code>Pod</code> 是 <code>Kubernetes</code> 创建或部署的最小/最简单的基本单位,一个 <code>Pod</code> 代表集群上正在运行的一个进程。</p></blockquote><blockquote><p>创建 <code>Deployment</code> 时,<code>Kubernetes</code> 会创建了一个 <code>Pod</code> 来托管应用。<code>Pod</code> 是 <code>Kubernetes</code> 中一个抽象化概念,由一个或多个容器组合在一起得共享资源<br><code>Pod</code> 代表部署的一个单位:<code>Kubernetes</code> 中单个应用的实例,它可能由单个容器或多个容器共享组成的资源。</p></blockquote><h2 id="Kubernetes-Replica-Sets-概述"><a href="#Kubernetes-Replica-Sets-概述" class="headerlink" title="Kubernetes Replica Sets 概述"></a><strong>Kubernetes Replica Sets</strong> 概述</h2><blockquote><p><code>ReplicaSet(RS)</code> 是 <code>Replication Controller(RC)</code> 的升级版本。</p></blockquote><blockquote><p>主要被 <code>Deployments</code> 用作 <code>pod</code> 机制的创建、删除和更新。当使用 <code>Deployment</code> 时,你不必担心创建 <code>pod</code> 的 <code>ReplicaSets</code>,因为可以通过 <code>Deployment</code> 实现管理 <code>ReplicaSets</code></p></blockquote><h2 id="Kubernetes-Deployment-概述"><a href="#Kubernetes-Deployment-概述" class="headerlink" title="Kubernetes Deployment 概述"></a><strong>Kubernetes Deployment</strong> 概述</h2><blockquote><p><code>Deployment</code> 为 <code>Pod</code> 和 <code>Replica Set</code>(升级版的 Replication Controller)提供声明式更新。</p></blockquote><blockquote><p>负责创建和更新应用,应用实例创建完成后,<code>Kubernetes Deployment Controller</code> 会持续监视这些实例。如果管理实例的节点被关闭或删除,那么 <code>Deployment Controller</code> 将会替换它们,实现自我修复能力。</p></blockquote><h2 id="Kubernetes-Service-概述"><a href="#Kubernetes-Service-概述" class="headerlink" title="Kubernetes Service 概述"></a><strong>Kubernetes Service</strong> 概述</h2><blockquote><p><code>Kubernetes Service</code> 定义了这样一种抽象:一个 <code>Pod</code> 的逻辑分组,一种可以访问它们的策略 —— 通常称为微服务。这一组 Pod 能够被 Service 访问到,</p></blockquote><h2 id="参考"><a href="#参考" class="headerlink" title="参考"></a>参考</h2><ul><li><a href="http://docs.kubernetes.org.cn/">Kubernetes中文社区|中文文档</a> </li><li><a href="http://docs.kubernetes.org.cn/683.html">Kubernetes kubectl 命令表</a></li><li><a href="https://blog.csdn.net/ucsheep/article/details/81781509">k8s(Kubernetes)中Pod,Deployment,ReplicaSet,Service之间关系分析</a></li></ul>]]></content>
<categories>
<category> 工程部署 </category>
</categories>
<tags>
<tag> k8s </tag>
<tag> Deployment/ReplicaSet/Service/pod </tag>
</tags>
</entry>
<entry>
<title>linux常用命令</title>
<link href="/passages/linux%E5%B8%B8%E7%94%A8%E5%91%BD%E4%BB%A4/"/>
<url>/passages/linux%E5%B8%B8%E7%94%A8%E5%91%BD%E4%BB%A4/</url>
<content type="html"><![CDATA[<p><code>linux</code> 常用命令备忘</p><span id="more"></span><h1 id="新手常用的linux命令"><a href="#新手常用的linux命令" class="headerlink" title="新手常用的linux命令"></a>新手常用的linux命令</h1><blockquote><p>命令名称 [命令参数] [命令对象]</p></blockquote><p>注意,命令名称、命令参数、命令对象之间请用空格键分隔。</p><p>命令对象一般是指要处理的文件、目录、用户等资源,而命令参数可以用长格式(完整的选项名称),也可以用短格式(单个字母的缩写),两者分别用–与-作为前缀。</p><p>命令参数的长格式与短格式示例<br>长格式 <code>man --help</code><br>短格式 <code>man -h</code></p><h2 id="常用系统工作命令"><a href="#常用系统工作命令" class="headerlink" title="常用系统工作命令"></a>常用系统工作命令</h2><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="section"># echo命令用于在shell中打印shell变量的值,或者直接输出指定的字符串</span></span><br><span class="line">echo 命令: echo(选项)(参数)</span><br><span class="line"></span><br><span class="line"><span class="section"># date命令是显示或设置系统时间与日期。</span></span><br><span class="line">date 命令: date(选项)(参数)</span><br><span class="line"></span><br><span class="line"><span class="section"># reboot命令用来重新启动正在运行的Linux操作系统。</span></span><br><span class="line">reboot 命令: reboot(选项)</span><br><span class="line"></span><br><span class="line"><span class="section"># poweroff命令用来关闭计算机操作系统并且切断系统电源。</span></span><br><span class="line">poweroff 命令: poweroff(选项)</span><br><span class="line"></span><br><span class="line"><span class="section"># wget命令用来从指定的URL下载文件</span></span><br><span class="line">wget 命令: wget(选项)(参数)</span><br><span class="line"></span><br><span class="line"><span class="section"># ps命令用于报告当前系统的进程状态。</span></span><br><span class="line">ps 命令: ps(选项) ps -ef | grep ""</span><br><span class="line"></span><br><span class="line"><span class="section"># top命令可以实时动态地查看系统的整体运行情况,</span></span><br><span class="line">top 命令: top(选项)</span><br><span class="line"></span><br><span class="line"><span class="section"># pidof命令用于查找指定名称的进程的进程号id号。</span></span><br><span class="line">pidof 命令: pidof(选项)(参数)</span><br><span class="line"></span><br><span class="line"><span class="section"># kill命令用来删除执行中的程序或工作 kill -9 进程 强制删除</span></span><br><span class="line">kill 命令: kill(选项)(参数)</span><br><span class="line"></span><br><span class="line"><span class="section"># killall命令使用进程的名称来杀死进程,使用此指令可以杀死一组同名进程</span></span><br><span class="line">killall 命令</span><br></pre></td></tr></table></figure><p>如果我们在系统终端中执行一个命令后想立即停止它,可以同时按下Ctrl + C组合键(生产环境中比较常用的一个快捷键),这样将立即终止该命令的进程。或者,如果有些命令在执行时不断地在屏幕上输出信息,影响到后续命令的输入,则可以在执行命令时在末尾添加上一个&符号,这样命令将进入系统后台来执行。</p><h2 id="系统状态检测命令"><a href="#系统状态检测命令" class="headerlink" title="系统状态检测命令"></a>系统状态检测命令</h2><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="section"># ifconfig命令被用于配置和显示Linux内核中网络接口的网络参数</span></span><br><span class="line">ifconfig 命令: ifconfig(参数)</span><br><span class="line"></span><br><span class="line"><span class="section"># uname命令用于打印当前系统相关信息</span></span><br><span class="line">uname 命令: uname(选项)</span><br><span class="line"></span><br><span class="line"><span class="section"># uptime命令能够打印系统总共运行了多长时间和系统的平均负载。</span></span><br><span class="line">uptime 命令: uptime(选项)</span><br><span class="line"></span><br><span class="line"><span class="section"># free命令可以显示当前系统未使用的和已使用的内存数目,显示被内核使用的内存缓冲区。</span></span><br><span class="line">free 命令: free(选项)</span><br><span class="line"></span><br><span class="line"><span class="section"># who命令是显示目前登录系统的用户信息</span></span><br><span class="line">who 命令: who(选项)(参数)</span><br><span class="line"></span><br><span class="line"><span class="section"># last命令用于显示用户最近登录信息</span></span><br><span class="line">last 命令: last(选项)(参数)</span><br><span class="line"></span><br><span class="line"><span class="section"># history命令用于显示指定数目的指令命令</span></span><br><span class="line">history 命令: history(选项)(参数)</span><br><span class="line"></span><br></pre></td></tr></table></figure><h2 id="工作目录切换命令"><a href="#工作目录切换命令" class="headerlink" title="工作目录切换命令"></a>工作目录切换命令</h2><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="section"># 以绝对路径的方式显示用户当前工作目录</span></span><br><span class="line">pwd 命令: pwd(选项)</span><br><span class="line"></span><br><span class="line"><span class="section"># cd命令用来切换工作目录至dirname</span></span><br><span class="line">cd 命令: cd (选项) (参数) </span><br><span class="line"></span><br><span class="line"><span class="section"># ls命令用来显示目标列表</span></span><br><span class="line">ls 命令: ls(选项)(参数) </span><br></pre></td></tr></table></figure><h2 id="文本文件编辑命令"><a href="#文本文件编辑命令" class="headerlink" title="文本文件编辑命令"></a>文本文件编辑命令</h2><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="section"># cat命令连接文件并打印到标准输出设备上,cat经常用来显示文件的内容,</span></span><br><span class="line">cat 命令: cat(选项)(参数)</span><br><span class="line"></span><br><span class="line"><span class="section"># more命令是一个基于vi编辑器文本过滤器,它以全屏幕的方式按页显示文本文件的内容</span></span><br><span class="line"><span class="section"># more名单中内置快捷键,H-获得帮助信息,Enter-向下翻滚一行,空格-向下滚动一屏,Q-退出命令。</span></span><br><span class="line">more 命令: more(语法)(参数)</span><br><span class="line"></span><br><span class="line"><span class="section"># head命令用于显示文件的开头的内容</span></span><br><span class="line"><span class="section"># 默认情况下,head命令显示文件的头10行内容。</span></span><br><span class="line">head 命令: head(选项)(参数)</span><br><span class="line"></span><br><span class="line"><span class="section"># tail命令用于输入文件中的尾部内容。</span></span><br><span class="line"><span class="section"># tail命令默认在屏幕上显示指定文件的末尾10行</span></span><br><span class="line">tail 命令: tail(选项)(参数)</span><br><span class="line"></span><br><span class="line"><span class="section"># tr命令可以对来自标准输入的字符进行替换、压缩和删除</span></span><br><span class="line">tr 命令: tr(选项)(参数)</span><br><span class="line"></span><br><span class="line"><span class="section"># wc命令用来计算数字。</span></span><br><span class="line">wc 命令: wc(选项)(参数)</span><br><span class="line"></span><br><span class="line"><span class="section"># stat命令用于显示文件的状态信息。</span></span><br><span class="line">stat 命令: stat(选项)(参数)</span><br><span class="line"></span><br><span class="line"><span class="section"># cut命令用来显示行中的指定部分,删除文件中指定字段。</span></span><br><span class="line">cut 命令: cut(选项)(参数)</span><br><span class="line"></span><br><span class="line"><span class="section"># diff命令在最简单的情况下,比较给定的两个文件的不同</span></span><br><span class="line">diff 命令: diff(选项)(参数)</span><br></pre></td></tr></table></figure><h2 id="文件目录管理命令"><a href="#文件目录管理命令" class="headerlink" title="文件目录管理命令"></a>文件目录管理命令</h2><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="section"># 一是用于把已存在文件的时间标签更新为系统当前的时间(默认方式)</span></span><br><span class="line"><span class="section"># 二是用来创建新的空文件</span></span><br><span class="line">touch 命令: touch(选项)(参数)</span><br><span class="line"></span><br><span class="line"><span class="section"># mkdir命令用来创建目录</span></span><br><span class="line">mkdir 命令: mkdir (选项)(参数)</span><br><span class="line"></span><br><span class="line"><span class="section"># cp命令用来将一个或多个源文件或者目录复制到指定的目的文件或目录。</span></span><br><span class="line">cp 命令: cp(选项)(参数)</span><br><span class="line"></span><br><span class="line"><span class="section"># mv命令用来对文件或目录重新命名,或者将文件从一个目录移到另一个目录中。</span></span><br><span class="line">mv 命令: mv(选项)(参数)</span><br><span class="line"></span><br><span class="line"><span class="section"># rm命令可以删除一个目录中的一个或多个文件或目录,也可以将某个目录及其下属的所有文件及其子目录均删除掉。</span></span><br><span class="line">rm 命令: rm (选项)(参数) rm -rf (参数)</span><br><span class="line"></span><br><span class="line"><span class="section"># dd命令用于复制文件并对原文件的内容进行转换和格式化处理</span></span><br><span class="line">dd 命令: dd(选项)</span><br><span class="line"></span><br><span class="line"><span class="section"># file命令用来探测给定文件的类型。</span></span><br><span class="line"><span class="section"># file命令对文件的检查分为文件系统、魔法幻数检查和语言检查3个过程。</span></span><br><span class="line">file 命令: file(选项)(参数)</span><br></pre></td></tr></table></figure><h2 id="打包压缩与搜索命令"><a href="#打包压缩与搜索命令" class="headerlink" title="打包压缩与搜索命令"></a>打包压缩与搜索命令</h2><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="section"># tar命令可以为linux的文件和目录创建档案。</span></span><br><span class="line">tar 命令: tar(选项)(参数)</span><br><span class="line"></span><br><span class="line"><span class="section"># grep是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹配的行打印出来。</span></span><br><span class="line"><span class="section"># grep match<span class="emphasis">_pattern file_</span>name cat file<span class="emphasis">_name | grep "text"</span></span></span><br><span class="line"><span class="emphasis"><span class="section">grep 命令</span></span></span><br><span class="line"><span class="emphasis"><span class="section"></span></span></span><br><span class="line"><span class="emphasis"><span class="section"># find命令用来在指定目录下查找文件。</span></span></span><br><span class="line"><span class="emphasis"><span class="section">find 命令: find(选项)(参数)</span></span></span><br></pre></td></tr></table></figure><h1 id="参考"><a href="#参考" class="headerlink" title="参考"></a>参考</h1><ul><li><a href="http://man.linuxde.net/">Linux命令大全(手册)_Linux常用命令行实例详解_Linux命令学习手册</a></li><li><a href="https://www.cnblogs.com/yjd_hycf_space/p/7730690.html">Linux常用命令大全</a></li></ul>]]></content>
<categories>
<category> 工程部署 </category>
</categories>
<tags>
<tag> linux </tag>
</tags>
</entry>
<entry>
<title>pm2学习</title>
<link href="/passages/pm2%E5%AD%A6%E4%B9%A0/"/>
<url>/passages/pm2%E5%AD%A6%E4%B9%A0/</url>
<content type="html"><![CDATA[<p><code>pm2</code> 基础学习</p><span id="more"></span><h2 id="说明"><a href="#说明" class="headerlink" title="说明"></a>说明</h2><p><code>PM2</code> 是 <code>nodejs进程</code> 管理工具,内置负载均衡。它可以帮助您保持Node应用程序永久活动,重起这些node应用程序也不需要停机,并简化常见的系统管理任务。</p><h2 id="主要特性"><a href="#主要特性" class="headerlink" title="主要特性"></a>主要特性</h2><ul><li>内建负载均衡(使用Node cluster 集群模块)</li><li>后台运行</li><li>0秒停机重载–pm2 reload</li><li>具有Ubuntu和CentOS 的启动脚本, windows 则可用 pm2-windows-startup</li><li>控制台检测–pm2 monit</li></ul><blockquote><p>上面特性已体验,下面暂未体验到</p></blockquote><ul><li>停止不稳定的进程(避免无限循环)</li><li>提供 HTTP API</li><li>远程控制和实时的接口API ( Nodejs 模块,允许和PM2进程管理器交互 )</li></ul><h2 id="安装"><a href="#安装" class="headerlink" title="安装"></a>安装</h2><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="section"># 全局安装</span></span><br><span class="line">npm install pm2 -g</span><br></pre></td></tr></table></figure><h2 id="常用命令"><a href="#常用命令" class="headerlink" title="常用命令"></a>常用命令</h2><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br></pre></td><td class="code"><pre><span class="line"><span class="section"># start and add a process to your list</span></span><br><span class="line">pm2 start app.js</span><br><span class="line"></span><br><span class="line"><span class="section"># show your list</span></span><br><span class="line">pm2 ls</span><br><span class="line"></span><br><span class="line"><span class="section"># stop and delete a process from the list</span></span><br><span class="line"><span class="section"># Default process name is the filename without .js (eg: app for app.js).</span></span><br><span class="line"><span class="section"># Use --name or -n to change.</span></span><br><span class="line">pm2 delete app</span><br><span class="line"></span><br><span class="line"><span class="section"># stop the process (kill the process but keep it in the process list)</span></span><br><span class="line">pm2 stop app</span><br><span class="line"></span><br><span class="line"><span class="section"># start the process</span></span><br><span class="line">pm2 start app</span><br><span class="line"></span><br><span class="line"><span class="section"># both stop and start</span></span><br><span class="line">pm2 restart app</span><br><span class="line"></span><br><span class="line"><span class="section"># Use reload instead of restart for 0-seconds downtime reloads:</span></span><br><span class="line">pm2 reload app</span><br><span class="line"></span><br><span class="line"><span class="section"># Managing apps is straightforward:</span></span><br><span class="line">pm2 stop <span class="language-xml"><app_name|id|'all'|json_conf></span></span><br><span class="line">pm2 restart <span class="language-xml"><app_name|id|'all'|json_conf></span></span><br><span class="line">pm2 delete <span class="language-xml"><app_name|id|'all'|json_conf></span></span><br><span class="line"></span><br><span class="line"><span class="section"># To have more details on a specific application:</span></span><br><span class="line">pm2 describe <span class="language-xml"><id|app_name></span></span><br><span class="line"></span><br><span class="line"><span class="section"># To monitor logs, custom metrics, application information:</span></span><br><span class="line">pm2 monit</span><br><span class="line"></span><br><span class="line"><span class="section"># logs</span></span><br><span class="line">pm2 logs</span><br><span class="line"></span><br><span class="line"><span class="section"># PM2 can generates and configure a Startup Script to keep PM2 and your processes alive at every server restart.</span></span><br><span class="line"><span class="section"># PM2可以生成和配置启动脚本,以在每次服务器重新启动时保持PM2和您的进程活动。</span></span><br><span class="line">$ pm2 startup # Generate Startup Script</span><br><span class="line">$ pm2 save # Freeze your process list across server restart</span><br><span class="line">$ pm2 unstartup # Remove Startup Script</span><br><span class="line"></span><br><span class="line"><span class="section"># Updating PM2</span></span><br><span class="line">$ npm install pm2@latest -g # Install latest PM2 version</span><br><span class="line">$ pm2 update # Save process list, exit old PM2 & restore all processes</span><br></pre></td></tr></table></figure><h2 id="命令补全"><a href="#命令补全" class="headerlink" title="命令补全"></a>命令补全</h2><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><span class="line"><span class="section"># 后台运行pm2,启动4个app.js</span></span><br><span class="line"><span class="section"># 也可以把'max' 参数传递给 start</span></span><br><span class="line"><span class="section"># 正确的进程数目依赖于Cpu的核心数目</span></span><br><span class="line">$ pm2 start app.js -i 4</span><br><span class="line"><span class="section"># 命名进程</span></span><br><span class="line">$ pm2 start app.js --name my-api</span><br><span class="line"><span class="section"># 显示所有进程状态</span></span><br><span class="line">$ pm2 list</span><br><span class="line"><span class="section"># 监视所有进程</span></span><br><span class="line">$ pm2 monit</span><br><span class="line"><span class="section"># 显示所有进程日志</span></span><br><span class="line">$ pm2 logs</span><br><span class="line"><span class="section"># 停止所有进程</span></span><br><span class="line">$ pm2 stop all</span><br><span class="line"><span class="section"># 重启所有进程</span></span><br><span class="line">$ pm2 restart all</span><br><span class="line"><span class="section"># 0秒停机重载进程</span></span><br><span class="line">$ pm2 reload all</span><br><span class="line"><span class="section"># 停止指定的进程</span></span><br><span class="line">$ pm2 stop 0</span><br><span class="line"><span class="section"># 重启指定的进程</span></span><br><span class="line">$ pm2 restart 0</span><br><span class="line"><span class="section"># 产生init脚本保持进程活着</span></span><br><span class="line">$ pm2 startup</span><br><span class="line"><span class="section"># 运行健壮的 computer API endpoint (http:#localhost:9615)</span></span><br><span class="line">$ pm2 web</span><br><span class="line"><span class="section"># 杀死指定的进程</span></span><br><span class="line">$ pm2 delete 0</span><br><span class="line"><span class="section"># 杀死全部进程</span></span><br><span class="line">$ pm2 delete all</span><br></pre></td></tr></table></figure><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line"><span class="section">#运行进程的不同方式:</span></span><br><span class="line"></span><br><span class="line"><span class="section"># 根据有效CPU数目启动最大进程数目</span></span><br><span class="line">$ pm2 start app.js -i max</span><br><span class="line"><span class="section"># 启动3个进程</span></span><br><span class="line">$ pm2 start app.js -i 3</span><br><span class="line"><span class="section"># 用fork模式启动app.js而不是使用 cluster</span></span><br><span class="line">$ pm2 start app.js -x</span><br><span class="line"><span class="section"># 用fork模式启动 app.js 并且传递参数 (-a 23)</span></span><br><span class="line">$ pm2 start app.js -x -- -a 23</span><br><span class="line"><span class="section"># 启动一个进程并把它命名为 serverone</span></span><br><span class="line">$ pm2 start app.js --name serverone</span><br><span class="line"><span class="section"># 停止 serverone 进程</span></span><br><span class="line">$ pm2 stop serverone</span><br><span class="line"><span class="section"># 启动进程, 在 app.json里设置选项</span></span><br><span class="line">$ pm2 start app.json</span><br><span class="line"><span class="section"># 在--之后给 app.js 传递参数</span></span><br><span class="line">$ pm2 start app.js -i max -- -a 23</span><br><span class="line"><span class="section"># 启动 并 生成一个配置文件</span></span><br><span class="line">$ pm2 start app.js -i max -e err.log -o out.log</span><br><span class="line"><span class="section">#你也可以执行用其他语言编写的app(fork模式):</span></span><br><span class="line">$ pm2 start my-bash-script.sh -x --interpreter bash</span><br><span class="line">$ pm2 start my-python-script.py -x --interpreter python</span><br><span class="line"></span><br><span class="line"><span class="section">#集群模式:Node.js负载平衡和零停机重新加载</span></span><br><span class="line">$ pm2 start api.js -i <span class="language-xml"><span class="tag"><<span class="name">processes</span>></span></span> # 以集群模式启动Node.js应用程序,该应用程序将利用所有可用的CPU:</span><br><span class="line">$ pm2 reload all # Zero Downtime Reload</span><br></pre></td></tr></table></figure><h2 id="补充说明"><a href="#补充说明" class="headerlink" title="补充说明"></a>补充说明</h2><p>pm2 reload all # 常用于在集群模式(cluster mode)下,保持应用不停(Zero Downtime Reload)</p><p>pm2 startup # 开机启动,windows使用不行,推荐 <a href="https:#www.npmjs.com/package/pm2-windows-startup">pm2-windows-startup</a> 配合实现对应效果</p><h2 id="参考"><a href="#参考" class="headerlink" title="参考"></a>参考</h2><ul><li><a href="https://www.npmjs.com/package/pm2">npm-pm2</a></li><li><a href="https://pm2.io/doc/en/runtime/overview/?utm_source=pm2&utm_medium=website&utm_campaign=rebranding">pm2-官网</a></li><li><a href="https://www.npmjs.com/package/pm2-windows-startup">npm-pm2-windows-startup</a></li><li><a href="https://www.douban.com/note/314200231/">PM2 介绍</a></li><li><a href="https://cloud.tencent.com/developer/article/1348819">pm2常用命令</a></li></ul>]]></content>
<categories>
<category> 工程部署 </category>
</categories>
<tags>
<tag> pm2 </tag>
</tags>
</entry>
<entry>
<title>web 页面加载、解析、渲染过程</title>
<link href="/passages/web%E9%A1%B5%E9%9D%A2%E5%8A%A0%E8%BD%BD%E3%80%81%E8%A7%A3%E6%9E%90%E3%80%81%E6%B8%B2%E6%9F%93%E8%BF%87%E7%A8%8B/"/>
<url>/passages/web%E9%A1%B5%E9%9D%A2%E5%8A%A0%E8%BD%BD%E3%80%81%E8%A7%A3%E6%9E%90%E3%80%81%E6%B8%B2%E6%9F%93%E8%BF%87%E7%A8%8B/</url>
<content type="html"><![CDATA[<p><code>web</code> 页面加载、解析、渲染过程</p><span id="more"></span><h2 id="浏览器输入url到页面渲染"><a href="#浏览器输入url到页面渲染" class="headerlink" title="浏览器输入url到页面渲染"></a>浏览器输入url到页面渲染</h2><ol><li>用户输入URL地址</li><li>浏览器查询缓存,若有缓存,直接展示</li><li>浏览器解析URL解析出主机名</li><li><p>浏览器将主机名转换为服务器ip地址</p><p> 先查找本地DNS缓存,若没有,向浏览器默认DNS服务器发送查询请求,同时缓存</p></li><li>浏览器将端口号从URL解析出</li><li>浏览器向服务器发送TCP连接,三次握手</li><li>浏览器向服务器发送HTTP请求,请求数据包</li><li>服务器向浏览器返回HTTP响应,响应报文</li><li>关闭连接,浏览器解析文档,解析成DOM树,解析CSS样式,渲染页面</li></ol><h2 id="DOM和JavaScript的关系"><a href="#DOM和JavaScript的关系" class="headerlink" title="DOM和JavaScript的关系"></a>DOM和JavaScript的关系</h2><blockquote><p><code>文档对象模型(DOM)</code> 是一个独立于语言,用于操作 XML 和 HTML 文档的 API.</p></blockquote><p>DOM是一个与语言无关的API,别的语言也可以实现操作DOM的具体api,但是它在浏览器中是用JavaScript来实现的,因此,DOM是现在JavaScript编码中很重要的一部分,因为JavaScript很多时候都在操作底层文档。</p><h2 id="操作DOM会很慢"><a href="#操作DOM会很慢" class="headerlink" title="操作DOM会很慢"></a>操作DOM会很慢</h2><p>DOM 和 JavaScript 是独立实现的,通过 js 操作 dom, 需要先连接,然后进行操作。<br>次数多,则操作会很慢</p><h2 id="网页生成过程"><a href="#网页生成过程" class="headerlink" title="网页生成过程"></a>网页生成过程</h2><p><img src="/images/网页渲染过程.png"/></p><ol><li>将HTML构建成一个<code>DOM树</code>(Document Object Model 文档对象模型)</li><li>将CSS构造<code>CSSOM树</code>(CSS Object Model CSS对象模型)</li><li><p>根据DOM树和CSSOM来构造 <code>Rendering Tree</code>(渲染树)</p><p> 注意:Rendering Tree 渲染树并不等同于 DOM 树,因为一些像 Header 或 display:none 的东西就没必要放在渲染树中了。</p></li><li>生成<code>布局(layout)</code>,计算出每个节点在屏幕中的位置</li><li>将布局<code>绘制(paint)</code>在屏幕上</li></ol><blockquote><p>“生成布局”(flow)和”绘制”(paint)这两步,合称为”渲染”(render),耗时较多</p></blockquote><p><img src="/images/渲染.png"/></p><h2 id="重排和重绘"><a href="#重排和重绘" class="headerlink" title="重排和重绘"></a>重排和重绘</h2><blockquote><p><code>Reflow(回流/重排)</code>:当它发现了某个部分发生了变化影响了布局,渲染树需要重新计算。</p></blockquote><blockquote><p><code>Repaint(重绘)</code>: 根据元素的新属性重新绘制,使元素呈现新的外观。重绘不会带来重新布局,并不一定伴随重排</p></blockquote><p>重排一定会引起重绘,而重绘不一定会引起重排</p><h3 id="reflow原因"><a href="#reflow原因" class="headerlink" title="reflow原因"></a>reflow原因</h3><ul><li>页面初始渲染</li><li>浏览器窗口大小发生改变</li><li>添加/删除可见DOM元素</li><li>改变元素位置</li><li>改变元素尺寸(宽、高、内外边距、边框等)</li><li>改变元素内容(文本或图片等)</li><li>元素字体大小变化</li><li>添加或者删除可见的DOM元素</li><li>激活CSS伪类(例如::hover)</li><li>设置style属性(例如:width/height 等)</li><li>查询某些属性或调用某些方法(例如:scrollIntoViewIfNeeded())</li></ul><h3 id="避免reflow"><a href="#避免reflow" class="headerlink" title="避免reflow"></a>避免reflow</h3><ol><li>DOM 的多个读操作(或多个写操作),应该放在一起。不要两个读操作之间,加入一个写操作</li><li>如果某个样式是通过重排得到的,那么最好缓存结果。避免下一次用到的时候,浏览器又要重排</li><li>不要一条条地改变样式,而要通过改变class,或者csstext属性,一次性地改变样式</li><li>尽量使用离线DOM,而不是真实的网面DOM,来改变元素样式。<br> 比如,操作Document Fragment对象,完成后再把这个对象加入DOM。再比如,使用 cloneNode() 方法,在克隆的节点上进行操作,然后再用克隆的节点替换原始节点。</li><li>先将元素设为display: none(需要1次重排和重绘),然后对这个节点进行100次操作,最后再恢复显示(需要1次重排和重绘)。这样一来,你就用两次重新渲染,取代了可能高达100次的重新渲染</li><li>position属性为absolute或fixed的元素,重排的开销会比较小,因为不用考虑它对其他元素的影响。</li><li>只在必要的时候,才将元素的display属性为可见,因为不可见的元素不影响重排和重绘。另外,visibility:hidden的元素只对重绘有影响,不影响重排</li><li>使用虚拟DOM的脚本库,比如React等</li><li>使用 window.requestAnimationFrame()、window.requestIdleCallback() 这两个方法调节重新渲染</li><li>少用table, table元素的重排和重绘成本,要高于div元素</li></ol>]]></content>
<categories>
<category> 页面加载 </category>
</categories>
<tags>
<tag> 页面加载/页面解析/页面渲染 </tag>
<tag> 重排 </tag>
<tag> 重绘 </tag>
</tags>
</entry>
<entry>
<title>HTTP 状态码</title>
<link href="/passages/HTTP%E7%8A%B6%E6%80%81%E7%A0%81/"/>
<url>/passages/HTTP%E7%8A%B6%E6%80%81%E7%A0%81/</url>
<content type="html"><![CDATA[<p><code>HTTP Status Code</code> 简单知识</p><span id="more"></span><h2 id="HTTP状态码"><a href="#HTTP状态码" class="headerlink" title="HTTP状态码"></a>HTTP状态码</h2><p>当浏览者访问一个网页时,浏览者的浏览器会向网页所在服务器发出请求。<br>当浏览器接收并显示网页前,此网页所在的服务器会返回一个包含HTTP状态码的信息头(server header)用以响应浏览器的请求。</p><h2 id="常见状态码"><a href="#常见状态码" class="headerlink" title="常见状态码"></a>常见状态码</h2><h3 id="1"><a href="#1" class="headerlink" title="1**"></a>1**</h3><p><code>信息,服务器收到请求,需要请求者继续执行操作</code></p><ul><li>100: Continue, 继续. 客户端应继续其请求</li></ul><h3 id="2"><a href="#2" class="headerlink" title="2**"></a>2**</h3><p><code>成功,操作被成功接收并处理</code></p><ul><li>200: OK, 请求成功. 一般用于GET与POST请求</li><li>204: No Content, 无内容. 服务器成功处理,但未返回内容。</li><li>205: Reset Content, 重置内容. 服务器处理成功,用户终端(例如:浏览器)应重置文档视图</li></ul><h3 id="3"><a href="#3" class="headerlink" title="3**"></a>3**</h3><p><code>重定向,需要进一步的操作以完成请求</code></p><ul><li>301: Moved Permanently, 永久移动. 请求的资源已被永久的移动到新URI</li><li>302: Found, 临时移动。与301类似。但资源只是临时被移动</li><li>304: Not Modified, 未修改。所请求的资源未修改,服务器不会返回任何资源,使用缓存</li><li>307: Temporary Redirect, 临时重定向。与302类似。使用GET请求重定向</li></ul><h3 id="4"><a href="#4" class="headerlink" title="4**"></a>4**</h3><p><code>客户端错误,请求包含语法错误或无法完成请求</code></p><ul><li>400: Bad Request, 客户端请求的语法错误,服务器无法理解</li><li>401: Unauthorized 请求要求用户的身份认证</li><li>403: Forbidden, 服务器理解请求客户端的请求,但是拒绝执行此请求</li><li>404: Not Found, 服务器无法根据客户端的请求找到资源(网页)</li><li>405: Method Not Allowed, 客户端请求中的方法被禁止</li><li>408: Request Time-out, 服务器等待客户端发送的请求时间过长,超时</li><li>414: Request-URI Too Large, 请求的URI过长(URI通常为网址),服务器无法处理</li></ul><h3 id="5"><a href="#5" class="headerlink" title="5**"></a>5**</h3><p><code>服务器错误,服务器在处理请求的过程中发生了错误</code></p><ul><li>500: Internal Server Error, 服务器内部错误,无法完成请求</li><li>501: Not Implemented, 服务器不支持请求的功能,无法完成请求</li><li>502: Bad Gateway, 作为网关或者代理工作的服务器尝试执行请求时,从远程服务器接收到了一个无效的响应</li><li>503: Service Unavailable, 由于超载或系统维护,服务器暂时的无法处理客户端的请求</li><li>504: Gateway Time-out, 充当网关或代理的服务器,未及时从远端服务器获取请求</li><li>505: HTTP Version not supported, 服务器不支持请求的HTTP协议的版本,无法完成处理</li></ul>]]></content>
<categories>
<category> 请求 </category>
</categories>
<tags>
<tag> HTTP Status Code </tag>
</tags>
</entry>
<entry>
<title>Get 与 Post 区别</title>
<link href="/passages/get%E4%B8%8Epost%E5%8C%BA%E5%88%AB/"/>
<url>/passages/get%E4%B8%8Epost%E5%8C%BA%E5%88%AB/</url>
<content type="html"><![CDATA[<p><code>Get</code> 与 <code>POST</code> 的区别</p><span id="more"></span><h2 id="什么是-HTTP"><a href="#什么是-HTTP" class="headerlink" title="什么是 HTTP ?"></a>什么是 HTTP ?</h2><blockquote><p>超文本传输协议(HTTP)的设计目的是保证客户机与服务器之间的通信。<br>HTTP 的工作方式是客户机与服务器之间的请求-应答协议。<br>web 浏览器可能是客户端,而计算机上的网络应用程序也可能作为服务器端。<br>举例:客户端(浏览器)向服务器提交 HTTP 请求;服务器向客户端返回响应。响应包含关于请求的状态信息以及可能被请求的内容。</p></blockquote><h2 id="HTTP请求方法:GET-和-POST"><a href="#HTTP请求方法:GET-和-POST" class="headerlink" title="HTTP请求方法:GET 和 POST"></a>HTTP请求方法:GET 和 POST</h2><ul><li>GET - 从指定的资源请求数据。</li><li>POST - 向指定的资源提交要被处理的数据</li></ul><h2 id="区别"><a href="#区别" class="headerlink" title="区别"></a>区别</h2><ul><li><code>GET</code> 参数通过 url 传递,<code>POST</code> 放在 request body中</li><li><code>GET</code> 请求在URL中传送的参数是有长度限制的(2048 个字符),而 <code>POST</code> 没有</li><li><code>GET</code> 比 <code>post</code> 更不安全,因为参数直接暴露在url中,所以不能用来传递敏感信息</li><li><code>GET</code> 请求只能进行url编码,而 <code>POST</code> 支持多种编码方式</li><li><code>GET</code> 请求会被浏览器主动cache,而 <code>POST</code> 不会,除非手动设置</li><li><code>GET</code> 请求参数会被完整保留在浏览器历史记录里,而 <code>POST</code> 中的参数不会被保留</li><li><code>GET</code> 在浏览器回退时是无害的,而 <code>POST</code> 会再次提交请求</li><li><code>GET</code> 只接受ASCII字符的参数的数据类型,,而 <code>POST</code> 没有限制</li><li><code>GET</code> 产生的URL地址可以被Bookmark-书签,而 <code>POST</code> 不可以。</li></ul><h2 id="本质"><a href="#本质" class="headerlink" title="本质"></a>本质</h2><ul><li><code>GET</code> 和 <code>POST</code> 本质上就是TCP链接,并无差别。但是由于HTTP的规定和浏览器/服务器的限制,导致他们在应用过程中体现出一些不同。</li><li><p><code>GET</code> 产生一个TCP数据包, <code>POST</code> 产生两个TCP数据包。</p><ul><li>对于 <code>GET</code> 方式的请求,浏览器会把http header和data一并发送出去,服务器响应200(返回数据);</li><li>对于 <code>POST</code>,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)。</li><li>据研究,在网络环境好的情况下,发一次包的时间和发两次包的时间差别基本可以无视。而在网络环境差的情况下,两次包的TCP在验证数据包完整性上,有非常大的优点。</li><li>并不是所有浏览器都会在 <code>POST</code> 中发送两次包,Firefox就只发送一次。</li></ul></li></ul>]]></content>
<categories>
<category> 请求 </category>
</categories>
<tags>
<tag> Get </tag>
<tag> Post </tag>
</tags>
</entry>
<entry>
<title>create脚手架使用antd(开启less,css module,定制主题)</title>
<link href="/passages/create%E8%84%9A%E6%89%8B%E6%9E%B6%E4%BD%BF%E7%94%A8antd(less,%20css-module,%E4%B8%BB%E9%A2%98)/"/>
<url>/passages/create%E8%84%9A%E6%89%8B%E6%9E%B6%E4%BD%BF%E7%94%A8antd(less,%20css-module,%E4%B8%BB%E9%A2%98)/</url>
<content type="html"><![CDATA[<p>使用 <code>create-react-app</code> 脚手架开发时, 如何配置 <code>antd</code>, 同时开启 less, css module, 及主题定制</p><span id="more"></span><h2 id="create-react-app"><a href="#create-react-app" class="headerlink" title="create-react-app"></a>create-react-app</h2><p>使用 <code>create-react-app</code> 脚手架开发时, 命令 <code>yarn run eject</code> 暴露配置。</p><h2 id="webpack-配置"><a href="#webpack-配置" class="headerlink" title="webpack 配置"></a>webpack 配置</h2><p>在暴露出的 <code>webpack.config.dev.js</code> 和 <code>webpack.config.prod.js</code> 中进行配置修改即可。</p><h3 id="antd-按需加载"><a href="#antd-按需加载" class="headerlink" title="antd 按需加载"></a>antd 按需加载</h3><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//安装依赖</span></span><br><span class="line">npm install babel-plugin-<span class="keyword">import</span> --save-dev</span><br><span class="line"></span><br><span class="line"><span class="comment">//修改配置</span></span><br><span class="line"><span class="comment">// Process JS with Babel.</span></span><br><span class="line">{</span><br><span class="line"> <span class="attr">test</span>: <span class="regexp">/\.(js|jsx|mjs)$/</span>,</span><br><span class="line"> <span class="attr">include</span>: paths.<span class="property">appSrc</span>,</span><br><span class="line"> <span class="attr">loader</span>: <span class="built_in">require</span>.<span class="title function_">resolve</span>(<span class="string">'babel-loader'</span>),</span><br><span class="line"> <span class="attr">options</span>: {</span><br><span class="line"> <span class="attr">plugins</span>: [ <span class="comment">//增加此配置,注意style:true 动态加载;style:css加载生成后的css文件</span></span><br><span class="line"> [<span class="string">'import'</span>, { <span class="attr">libraryName</span>: <span class="string">'antd'</span>, <span class="attr">style</span>: <span class="literal">true</span> }]</span><br><span class="line"> ],</span><br><span class="line"> <span class="comment">// This is a feature of `babel-loader` for webpack (not Babel itself).</span></span><br><span class="line"> <span class="comment">// It enables caching results in ./node_modules/.cache/babel-loader/</span></span><br><span class="line"> <span class="comment">// directory for faster rebuilds.</span></span><br><span class="line"> <span class="attr">cacheDirectory</span>: <span class="literal">true</span>,</span><br><span class="line"> },</span><br><span class="line">},</span><br></pre></td></tr></table></figure><h3 id="开启-css-modules-amp-amp-less"><a href="#开启-css-modules-amp-amp-less" class="headerlink" title="开启 css modules && less"></a>开启 css modules && less</h3><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//安装依赖</span></span><br><span class="line">npm install less-loader --save</span><br><span class="line"></span><br><span class="line"><span class="comment">//此处指定版本是因为less高版本与antd冲突</span></span><br><span class="line">npm install less@<span class="number">2.7</span><span class="number">.3</span> --save</span><br></pre></td></tr></table></figure><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//处理规则从下向上</span></span><br><span class="line">{</span><br><span class="line"> <span class="attr">test</span>: <span class="regexp">/\.(css|less)$/</span>, <span class="comment">//匹配css或less</span></span><br><span class="line"> <span class="attr">exclude</span>: [<span class="regexp">/node_modules/</span>], <span class="comment">//排除node_modules文件夹,避免开启css-module时 antd 冲突</span></span><br><span class="line"> <span class="attr">use</span>: [</span><br><span class="line"> <span class="built_in">require</span>.<span class="title function_">resolve</span>(<span class="string">'style-loader'</span>),</span><br><span class="line"> {</span><br><span class="line"> <span class="attr">loader</span>: <span class="built_in">require</span>.<span class="title function_">resolve</span>(<span class="string">'css-loader'</span>),</span><br><span class="line"> <span class="attr">options</span>: { <span class="comment">//开启,且指定localIdentName,类名形式</span></span><br><span class="line"> <span class="attr">importLoaders</span>: <span class="number">1</span>,</span><br><span class="line"> <span class="attr">modules</span>: <span class="literal">true</span>,</span><br><span class="line"> <span class="attr">localIdentName</span>: <span class="string">'[name]__[local]__[hash:base64:5]'</span>,</span><br><span class="line"> },</span><br><span class="line"> },</span><br><span class="line"> {</span><br><span class="line"> <span class="attr">loader</span>: <span class="built_in">require</span>.<span class="title function_">resolve</span>(<span class="string">'postcss-loader'</span>),</span><br><span class="line"> <span class="attr">options</span>: {</span><br><span class="line"> <span class="comment">// Necessary for external CSS imports to work</span></span><br><span class="line"> <span class="comment">// https://github.com/facebookincubator/create-react-app/issues/2677</span></span><br><span class="line"> <span class="attr">ident</span>: <span class="string">'postcss'</span>,</span><br><span class="line"> <span class="attr">plugins</span>: <span class="function">() =></span> [</span><br><span class="line"> <span class="built_in">require</span>(<span class="string">'postcss-flexbugs-fixes'</span>),</span><br><span class="line"> <span class="title function_">autoprefixer</span>({</span><br><span class="line"> <span class="attr">browsers</span>: [</span><br><span class="line"> <span class="string">'>1%'</span>,</span><br><span class="line"> <span class="string">'last 4 versions'</span>,</span><br><span class="line"> <span class="string">'Firefox ESR'</span>,</span><br><span class="line"> <span class="string">'not ie < 9'</span>, <span class="comment">// React doesn't support IE8 anyway</span></span><br><span class="line"> ],</span><br><span class="line"> <span class="attr">flexbox</span>: <span class="string">'no-2009'</span>,</span><br><span class="line"> }),</span><br><span class="line"> ],</span><br><span class="line"> },</span><br><span class="line"> },</span><br><span class="line"> { <span class="comment">//开启less-loader</span></span><br><span class="line"> <span class="attr">loader</span>: <span class="built_in">require</span>.<span class="title function_">resolve</span>(<span class="string">'less-loader'</span>),</span><br><span class="line"> }</span><br><span class="line"> ],</span><br><span class="line">},</span><br></pre></td></tr></table></figure><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//处理规则从下向上</span></span><br><span class="line">{</span><br><span class="line"> <span class="attr">test</span>: <span class="regexp">/\.(css|less)$/</span>,</span><br><span class="line"> <span class="attr">include</span>: [<span class="regexp">/node_modules/</span>], <span class="comment">//针对node_modules, antd</span></span><br><span class="line"> <span class="attr">use</span>: [</span><br><span class="line"> <span class="built_in">require</span>.<span class="title function_">resolve</span>(<span class="string">'style-loader'</span>),</span><br><span class="line"> {</span><br><span class="line"> <span class="attr">loader</span>: <span class="built_in">require</span>.<span class="title function_">resolve</span>(<span class="string">'css-loader'</span>),</span><br><span class="line"> <span class="attr">options</span>: {</span><br><span class="line"> <span class="attr">importLoaders</span>: <span class="number">1</span></span><br><span class="line"> },</span><br><span class="line"> },</span><br><span class="line"> {</span><br><span class="line"> <span class="attr">loader</span>: <span class="built_in">require</span>.<span class="title function_">resolve</span>(<span class="string">'postcss-loader'</span>),</span><br><span class="line"> <span class="attr">options</span>: {</span><br><span class="line"> <span class="comment">// Necessary for external CSS imports to work</span></span><br><span class="line"> <span class="comment">// https://github.com/facebookincubator/create-react-app/issues/2677</span></span><br><span class="line"> <span class="attr">ident</span>: <span class="string">'postcss'</span>,</span><br><span class="line"> <span class="attr">plugins</span>: <span class="function">() =></span> [</span><br><span class="line"> <span class="built_in">require</span>(<span class="string">'postcss-flexbugs-fixes'</span>),</span><br><span class="line"> <span class="title function_">autoprefixer</span>({</span><br><span class="line"> <span class="attr">browsers</span>: [</span><br><span class="line"> <span class="string">'>1%'</span>,</span><br><span class="line"> <span class="string">'last 4 versions'</span>,</span><br><span class="line"> <span class="string">'Firefox ESR'</span>,</span><br><span class="line"> <span class="string">'not ie < 9'</span>, <span class="comment">// React doesn't support IE8 anyway</span></span><br><span class="line"> ],</span><br><span class="line"> <span class="attr">flexbox</span>: <span class="string">'no-2009'</span>,</span><br><span class="line"> }),</span><br><span class="line"> ],</span><br><span class="line"> },</span><br><span class="line"> },</span><br><span class="line"> { <span class="comment">//less处理</span></span><br><span class="line"> <span class="attr">loader</span>: <span class="built_in">require</span>.<span class="title function_">resolve</span>(<span class="string">'less-loader'</span>),</span><br><span class="line"> <span class="attr">options</span>: {</span><br><span class="line"> <span class="attr">modifyVars</span>: { <span class="comment">//修改主题</span></span><br><span class="line"> <span class="string">'@primary-color'</span>: <span class="string">'#1DA57A'</span></span><br><span class="line"> },</span><br><span class="line"> },</span><br><span class="line"> }</span><br><span class="line"> ],</span><br><span class="line">},</span><br></pre></td></tr></table></figure><h2 id="补充-Javascript-Decorators"><a href="#补充-Javascript-Decorators" class="headerlink" title="补充~Javascript Decorators"></a>补充~Javascript Decorators</h2><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm install babel-plugin-transform-decorators-legacy --save-dev</span><br></pre></td></tr></table></figure><h3 id="方式一"><a href="#方式一" class="headerlink" title="方式一"></a>方式一</h3><p><code>package.json</code> 中配置</p><figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">"babel"</span><span class="punctuation">:</span> <span class="punctuation">{</span></span><br><span class="line"> <span class="attr">"presets"</span><span class="punctuation">:</span> <span class="punctuation">[</span></span><br><span class="line"> <span class="string">"react-app"</span></span><br><span class="line"> <span class="punctuation">]</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"plugins"</span><span class="punctuation">:</span> <span class="punctuation">[</span></span><br><span class="line"> <span class="string">"transform-decorators-legacy"</span></span><br><span class="line"> <span class="punctuation">]</span></span><br><span class="line"><span class="punctuation">}</span><span class="punctuation">,</span></span><br></pre></td></tr></table></figure><h3 id="方式二"><a href="#方式二" class="headerlink" title="方式二"></a>方式二</h3><p><code>webpack</code> 中配置</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//修改webpack.config.dev.js配置文件</span></span><br><span class="line"><span class="comment">//babel-loader plugins中加入”transform-decorators-legacy”</span></span><br><span class="line">{</span><br><span class="line"> <span class="attr">test</span>: <span class="regexp">/\.(js|jsx|mjs)$/</span>,</span><br><span class="line"> <span class="attr">include</span>: paths.<span class="property">appSrc</span>,</span><br><span class="line"> <span class="attr">loader</span>: <span class="built_in">require</span>.<span class="title function_">resolve</span>(<span class="string">'babel-loader'</span>),</span><br><span class="line"> <span class="attr">options</span>: {</span><br><span class="line"> <span class="attr">plugins</span>: [</span><br><span class="line"> <span class="string">"transform-decorators-legacy"</span>,</span><br><span class="line"> [<span class="string">'import'</span>, { <span class="attr">libraryName</span>: <span class="string">'antd'</span>, <span class="attr">style</span>: <span class="string">'css'</span> }]</span><br><span class="line"> ],</span><br><span class="line"> <span class="comment">// This is a feature of `babel-loader` for webpack (not Babel itself).</span></span><br><span class="line"> <span class="comment">// It enables caching results in ./node_modules/.cache/babel-loader/</span></span><br><span class="line"> <span class="comment">// directory for faster rebuilds.</span></span><br><span class="line"> <span class="attr">cacheDirectory</span>: <span class="literal">true</span>,</span><br><span class="line"></span><br><span class="line"> },</span><br><span class="line">},</span><br></pre></td></tr></table></figure>]]></content>
<categories>
<category> react </category>
</categories>
<tags>
<tag> create-react-app </tag>
<tag> antd </tag>
<tag> less </tag>
<tag> css-module </tag>
<tag> 主题配置 </tag>
</tags>
</entry>
<entry>
<title>rap2部署说明</title>
<link href="/passages/rap2%E9%83%A8%E7%BD%B2%E8%AF%B4%E6%98%8E/"/>
<url>/passages/rap2%E9%83%A8%E7%BD%B2%E8%AF%B4%E6%98%8E/</url>
<content type="html"><![CDATA[<p><code>rap2</code>,阿里前端团队开源接口管理工具RAP第二代,部署说明</p><span id="more"></span><h2 id="介绍"><a href="#介绍" class="headerlink" title="介绍"></a>介绍</h2><p><code>rap2</code>-阿里前端团队开源接口管理工具RAP第二代</p><p><small style="vertical-align:middle;display:inline-block"><iframe src="https://ghbtns.com/github-btn.html?user=thx&repo=rap2-delos&type=watch&count=true" allowtransparency="true" frameborder="0" scrolling="0" width="110" height="20" style="width:110px;height:20px; background-color: transparent;"></iframe><iframe src="https://ghbtns.com/github-btn.html?user=thx&repo=rap2-delos&type=fork&count=true" allowtransparency="true" frameborder="0" scrolling="0" width="110" height="20" style="width:110px;height:20px; background-color: transparent;"></iframe><iframe src="https://ghbtns.com/github-btn.html?user=thx&repo=rap2-delos&type=follow&count=false" allowtransparency="true" frameborder="0" scrolling="0" width="170" height="20" style="width:170px;height:20px; background-color: transparent;"></iframe></small></p><h2 id="相关链接"><a href="#相关链接" class="headerlink" title="相关链接"></a>相关链接</h2><ul><li><a href="http://rapapi.org/org/index.do">官网</a></li><li><a href="https://github.com/thx/RAP">RAP-github</a></li><li><a href="https://github.com/thx/rap2-delos">RAP2-github</a></li><li><a href="https://incoder.org/2018/03/27/rap2/">Api 文档管理系统 RAP2环境搭建</a></li><li><a href="https://github.com/thx/rap2-delos/issues/119">非官方rap2-delos部署文档</a></li></ul><h2 id="部署"><a href="#部署" class="headerlink" title="部署"></a>部署</h2><h3 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h3><p><strong>RAP2</strong> 包含两个组件 客户端:<em><a href="https://github.com/thx/rap2-dolores">rap2-dolores</a></em> 和 服务端:<em><a href="https://github.com/thx/rap2-delos">rap2-delos</a></em></p><p>部署RAP2需要亲具有Node+Linux+MySQL的运维知识,如果亲对此不是很了解,建议用<a href="http://rap2.taobao.org">http://rap2.taobao.org</a> 线上版本就可以了。</p><h3 id="部署准备"><a href="#部署准备" class="headerlink" title="部署准备"></a>部署准备</h3><ul><li><a href="https://git-scm.com/downloads">git</a></li><li><a href="https://nodejs.org/zh-cn/download/">Node 8.9.4+</a></li><li><a href="https://www.mysql.com/cn/downloads/">MySQL 5.7+</a></li><li><a href="https://redis.io/download">Redis 4.0+</a></li><li><a href="https://code.visualstudio.com/download">VS code</a>(非必需)</li></ul><h2 id="服务端部署"><a href="#服务端部署" class="headerlink" title="服务端部署"></a>服务端部署</h2><p>下面先讲述 <code>rap2-delos</code> 服务端部署</p><h3 id="环境安装"><a href="#环境安装" class="headerlink" title="环境安装"></a>环境安装</h3><ol><li><code>node</code> 版本升级</li><li><code>mysql</code> 下载安装</li><li><code>redis</code> 下载安装</li><li><code>工程克隆</code> git clone <a href="https://github.com/thx/rap2-delos.git">https://github.com/thx/rap2-delos.git</a></li><li>导入 <code>VS Code</code> //这里的开发编辑工具推荐,当然你也可以用自己熟悉的开发工具</li></ol><blockquote><p>mysql 下载安装的时候,新手上路可以直接下载 <code>msi</code> 格式的安装包,而不是下载压缩包,不然还需要配置。</p><ul><li><a href="https://www.cnblogs.com/ayyl/p/5978418.html">参考-MySQL基础知识-安装MySQL</a></li></ul></blockquote><h3 id="Redis-安装说明"><a href="#Redis-安装说明" class="headerlink" title="Redis 安装说明"></a>Redis 安装说明</h3><ol><li><em><a href="https://incoder.org/2018/05/15/linux-build/">Linux 常用应用安装</a></em></li><li><em><a href="https://www.cnblogs.com/yougmi/p/6119259.html">Windows 下的 Redis 的启动</a></em></li><li><em><a href="https://jingyan.baidu.com/article/7f766daff725cf4101e1d0d1.html">windows下安装和启动redis服务</a></em></li></ol><p>说明:按照<strong>windows</strong>下相关操作即可。</p><p>常用命令</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*启动*/</span></span><br><span class="line">redis-server.<span class="property">exe</span> redis.<span class="property">windows</span>.<span class="property">conf</span></span><br><span class="line"></span><br><span class="line"><span class="comment">/*新窗口连接*/</span></span><br><span class="line">redis-cli.<span class="property">exe</span> 如果没有改默认配置的端口号</span><br><span class="line">redis-cli.<span class="property">exe</span> -h <span class="number">127.0</span><span class="number">.0</span><span class="number">.1</span> -p <span class="number">6379</span> 改了端口号</span><br><span class="line"></span><br><span class="line"><span class="comment">/*[13164] 27 Dec 20:57:07.820 # Creating Server TCP listening socket 127.0.0.1:6379*/</span></span><br><span class="line"><span class="comment">//错误解决</span></span><br><span class="line"><span class="number">1.</span> redis-cli.<span class="property">exe</span></span><br><span class="line"><span class="number">2.</span> shutdown</span><br><span class="line"><span class="number">3.</span> exit</span><br><span class="line"><span class="number">4.</span> redis-server.<span class="property">exe</span> redis.<span class="property">windows</span>.<span class="property">conf</span></span><br></pre></td></tr></table></figure><h3 id="创建数据库"><a href="#创建数据库" class="headerlink" title="创建数据库"></a>创建数据库</h3><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">进入mysql命令后执行</span><br><span class="line"><span class="keyword">CREATE</span> DATABASE IF <span class="keyword">NOT</span> <span class="keyword">EXISTS</span> RAP2_DELOS_APP <span class="keyword">DEFAULT</span> CHARSET utf8 <span class="keyword">COLLATE</span> utf8_general_ci;</span><br></pre></td></tr></table></figure><h3 id="配置文件"><a href="#配置文件" class="headerlink" title="配置文件"></a>配置文件</h3><ul><li>目录:rap2-delos/src/config</li><li>文件:config.dev.ts;其中dev,表示开发环境,其他同理</li><li>修改:config.dev.ts文件中db对象中username,password参数与本地或者开发环境的数据库信息匹配</li></ul><h3 id="项目启动"><a href="#项目启动" class="headerlink" title="项目启动"></a>项目启动</h3><ol><li><code>npm install</code> </li><li><code>npm run create-db</code> –初始化数据库</li><li><code>npm run check</code> –执行mocha测试用例和js代码规范检查</li><li><code>npm run dev</code> –启动开发模式的服务器 监视并在发生代码变更时自动重启</li><li><code>npm start</code> –启动生产模式服务器</li></ol><p><strong><a href="http://localhost:8080/">http://localhost:8080/</a></strong> 看到浏览器中如下提示,表示服务端delos已经部署成功</p><blockquote><p>RAP2后端服务已启动,请从前端服务(rap2-dolores)访问。 RAP2 back-end server is started, please visit via front-end service (rap2-dolores).</p></blockquote><h3 id="常见错误"><a href="#常见错误" class="headerlink" title="常见错误"></a>常见错误</h3><ol><li><p>执行 <strong>npm run create-d</strong> , 提示没有 <em>/dist</em></p><p> <code>原因</code>:运行 npm run build 就可以启动 ts 编译,把源文件编译到 dist 文件夹里面,就有 dist/ 目录了。</p></li><li><p>执行 <strong>npm run create-db</strong> 命令, Unable to connect to the database: { SequelizeConnectionError: Client does not support authentication protocol requested by server; consider upgrading MySQL client </p><p> <code>解决</code>:建议使用旧密码哈希算法, 执行如下sql</p> <figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">alter</span> <span class="keyword">user</span> <span class="string">'USER'</span>@<span class="string">'localhost'</span> identified <span class="keyword">with</span> mysql_native_password <span class="keyword">by</span> <span class="string">'PASSWORD'</span></span><br></pre></td></tr></table></figure><p> <em><a href="https://github.com/mysqljs/mysql/issues/1574">参考</a></em></p></li><li><p>执行 <strong>npm run create-db</strong> 命令,提示Unable to connect to the database:{ SequelizeAccessDeniedError: Access denied for user ‘root‘@’localhost’ (using password:NO)}</p><p> <code>原因</code>:未修改rap2-delos/src/config目录下数据库配置文件,或者是与文件中的数据库信息与之连接的数据库信息不匹配</p></li></ol><h2 id="客户端部署"><a href="#客户端部署" class="headerlink" title="客户端部署"></a>客户端部署</h2><ol><li><em>git clone <a href="https://github.com/thx/rap2-dolores">https://github.com/thx/rap2-dolores</a></em> –克隆工程</li><li><em>npm install</em></li><li><em>npm run dev</em> –开发模式, 自动监视改变后重新编译</li><li><em>npm run test</em> –备注:测试用例</li><li><em>npm run build</em> –生产模式, 编译React生产包</li><li><em>serve -s ./build -p 80</em> –用serve命令或nginx服务器路由到编译产出的build文件夹作为静态服务器即可</li></ol><h3 id="效果"><a href="#效果" class="headerlink" title="效果"></a>效果</h3><p>访问: <a href="http://localhost:3000">http://localhost:3000</a>, 即可看到对应功能</p><h2 id="使用总结"><a href="#使用总结" class="headerlink" title="使用总结"></a>使用总结</h2><ol><li><code>rap2-delos</code> 服务端启动 <em>npm run dev</em> {:&.moveIn}</li><li><code>rap2-dolores</code> 客户端启动 <em>npm run dev</em></li><li><code>redis</code> 缓存启动 <em>redis-server.exe redis.windows.conf</em></li><li><code>mysql</code> 数据库 <em>数据库连接</em></li><li><code>http://localhost:3000</code> <em>页面登录访问</em></li></ol>]]></content>
<categories>
<category> 工程部署 </category>
</categories>
<tags>
<tag> rap2 </tag>
<tag> 可视化接口管理工具 </tag>
</tags>
</entry>
<entry>
<title>react-router 之 HashRouter & BrowserRouter</title>
<link href="/passages/react-router%E9%97%AE%E9%A2%98/"/>
<url>/passages/react-router%E9%97%AE%E9%A2%98/</url>
<content type="html"><![CDATA[<p><code>react-router</code>,react 路由, <code>HashRouter</code> , <code>BrowserRouter</code> 区分。</p><span id="more"></span><h2 id="React-Router"><a href="#React-Router" class="headerlink" title="React-Router"></a>React-Router</h2><p>关于 <code>React-Router</code> v4 版本的两种路由方式 <code>HashRouter</code> , <code>BrowserRouter</code></p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="title class_">BrowserRouter</span> : <span class="attr">http</span>:<span class="comment">//localhost:3000/abc/def</span></span><br><span class="line"><span class="title class_">HashRouter</span>: <span class="attr">http</span>:<span class="comment">//localhost:3000/#/abc/def //hash地址就是指#号后面的url</span></span><br></pre></td></tr></table></figure><p><code>BrowserRouter</code> 基于 url 的 <code>pathName</code> 字段, <code>HashRouter</code> 则基于 <code>hash</code> 段。</p><h2 id="问题"><a href="#问题" class="headerlink" title="问题"></a>问题</h2><p>采用 <code>BrowserRouter</code> 写法</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><<span class="title class_">BrowserRouter</span>></span><br><span class="line"> <span class="language-xml"><span class="tag"><<span class="name">Route</span> <span class="attr">exact</span> <span class="attr">path</span>=<span class="string">"/"</span> <span class="attr">component</span>=<span class="string">{Index}/</span>></span></span></span><br><span class="line"> <span class="language-xml"><span class="tag"><<span class="name">Route</span> <span class="attr">path</span>=<span class="string">"/Search"</span> <span class="attr">component</span>=<span class="string">{Search}/</span>></span></span></span><br><span class="line"></<span class="title class_">BrowserRouter</span>></span><br></pre></td></tr></table></figure><p>开发时正常,打包后的静态页面空白, 访问时无法访问。</p><ol><li>查看发现静态资源引用异常,修改静态资源引用,改为相对路径,本身是 <code>/static/js -> ./static/js</code>。<br> 在package.json文件中添加homepage字段并设置为”.” || 直接修改生成后的静态页面引用。</li><li>发现静态资源正常,但是页面还是加载不到。</li><li>改为 <code>HashRouter</code> 可以访问。</li></ol><h2 id="原因"><a href="#原因" class="headerlink" title="原因"></a>原因</h2><ol><li><p>HashRouter<br> <code>hashHistory</code> 使用URL中的hash(#)部分去创建路由.<br> 举例来说,用户访问 /search, 实际会看到的是 <code>http://localhost:3000/#/search</code> 加载对应组件。<br> 访问 /(<code>http://localhost:3000/#/</code>)时 加载对应组件。</p></li><li><p>BrowserRouter<br> <code>browserHistory</code> 是使用 React-Router 的应用推荐的 history方案。它使用浏览器中的 History API 用于处理 URL.创建一个真实的URL.<br> 在 browserHistory 模式下,URL 是指向真实 URL 的资源路径。<br> 当通过真实 URL 访问网站的时候,由于路径是指向服务器的真实路径,但并没有对应物理路径/文件 ,实际所有内容是通过React-Router去渲染React组件,<br> 所以用户访问的资源不存在,则空白。</p></li></ol><h2 id="解决"><a href="#解决" class="headerlink" title="解决"></a>解决</h2><ol><li>采用 HashRouter–开发时可以,打包后的页面访问也可用。</li><li>采用 BrowserRouter—开发时可以,打包后的页面不可直接访问。<br> 本地开发时可以通过配置 webpack-devServer 的 historyApiFallback,create-react-app 已配置。<ul><li><a href="https://webpack.js.org/configuration/dev-server/#devserver-historyapifallback">devServer.historyApiFallback</a></li><li><a href="http://echizen.github.io/tech/2016/07-05-webpack-dev-server-react-router-config">webpack-dev-server使用react-router browserHistory的配置</a></li></ul></li><li>采用 BrowserRouter–服务端支持<ul><li>nginx 方式。指定目的文件夹,指定 index.html。全部导到index。</li><li>nodejs处理(express或koa).</li><li><a href="https://www.thinktxt.com/react/2017/02/26/react-router-browserHistory-refresh-404-solution.html">React-Router browserHistory浏览器刷新出现页面404解决方案</a></li></ul></li></ol><figure class="highlight nginx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="section">server</span> {</span><br><span class="line"> <span class="attribute">server_name</span> react.com;</span><br><span class="line"> <span class="attribute">listen</span> <span class="number">80</span>;</span><br><span class="line"></span><br><span class="line"> <span class="attribute">root</span> /user/src/React-Demo/dist;</span><br><span class="line"> <span class="attribute">index</span> index.html;</span><br><span class="line"> <span class="section">location</span> / {</span><br><span class="line"> <span class="attribute">try_files</span> <span class="variable">$uri</span> /index.html;</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> express = <span class="built_in">require</span>(<span class="string">'express'</span>);</span><br><span class="line"><span class="keyword">var</span> path = <span class="built_in">require</span>(<span class="string">'path'</span>);</span><br><span class="line"><span class="keyword">var</span> app = <span class="title function_">express</span>();</span><br><span class="line"></span><br><span class="line"><span class="comment">//设置静态资源目录</span></span><br><span class="line">app.<span class="title function_">use</span>(express.<span class="title function_">static</span>(path.<span class="title function_">join</span>(__dirname, <span class="string">'./build'</span>)));</span><br><span class="line"></span><br><span class="line"><span class="comment">//所有访问,都指定返回 index.html</span></span><br><span class="line"><span class="comment">//而index.html会根据React-Router规则去匹配任何一个route</span></span><br><span class="line">app.<span class="title function_">get</span>(<span class="string">'/*'</span>, <span class="keyword">function</span> (<span class="params">req, res</span>) {</span><br><span class="line"> res.<span class="title function_">sendFile</span>(path.<span class="title function_">join</span>(__dirname, <span class="string">'./build'</span>, <span class="string">'index.html'</span>));</span><br><span class="line">});</span><br><span class="line"></span><br><span class="line"><span class="comment">//设置服务器</span></span><br><span class="line"><span class="keyword">var</span> server = app.<span class="title function_">listen</span>(<span class="number">3001</span>, <span class="keyword">function</span> (<span class="params"></span>) {</span><br><span class="line"> <span class="keyword">var</span> host = server.<span class="title function_">address</span>().<span class="property">address</span>;</span><br><span class="line"> <span class="keyword">var</span> port = server.<span class="title function_">address</span>().<span class="property">port</span>;</span><br><span class="line"> <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">'众享后台 listening at http://%s:%s'</span>, host, port);</span><br><span class="line">});</span><br></pre></td></tr></table></figure><h2 id="补充"><a href="#补充" class="headerlink" title="补充"></a>补充</h2><ol><li>create-react-app 本地开发时使用 <code>BrowserRouter</code> 可以支持(webpack服务器-已配置)。</li><li>设置代理到 node 服务器时,注意是以 /api/ <code>开头</code>。</li><li>若路径中含有 /api/, 上步没有设置开头,则页面被转发到 node 服务器。<br> 返回的虽然设置了 <code>index.html</code>, 但是加载对应 <code>index.html</code> 中的静态资源的时候,返回的也是页面,不是静态资源。<br> 如果资源返回正常,页面是可以正常加载的,因为只要都返回静态页面,具体路由是有对应js处理的。</li></ol><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="string">"proxy"</span>: {</span><br><span class="line"> <span class="string">"^/api/"</span>: {</span><br><span class="line"> <span class="string">"target"</span>: <span class="string">"http://localhost:3001"</span>,</span><br><span class="line"> <span class="string">"changeOrigin"</span>: <span class="literal">true</span></span><br><span class="line"> }</span><br><span class="line">},</span><br></pre></td></tr></table></figure>]]></content>
<categories>
<category> react </category>
</categories>
<tags>
<tag> react-router </tag>
<tag> HashRouter </tag>
<tag> BrowserRouter </tag>
</tags>
</entry>
<entry>
<title>react-router 页面跳转</title>
<link href="/passages/react-router%E9%A1%B5%E9%9D%A2%E8%B7%B3%E8%BD%AC/"/>
<url>/passages/react-router%E9%A1%B5%E9%9D%A2%E8%B7%B3%E8%BD%AC/</url>
<content type="html"><![CDATA[<p><code>react-router</code>,页面跳转。</p><span id="more"></span><h2 id="props-match-params"><a href="#props-match-params" class="headerlink" title="props.match.params"></a>props.match.params</h2><p>此种方式,参数会显示在 <code>url地址栏</code> 上。</p><p>地址形式为 <code>/</code> 连接的形式。</p><ol><li><p><em>路由写法</em></p><p> 多个参数,以 <code>/</code> 分割, <code>?</code> 代表非必填, <code>*</code> 代表所有.</p> <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><<span class="title class_">Route</span> path=<span class="string">"/a/:data1/:data2?"</span> component={a}/></span><br><span class="line"></span><br><span class="line"><span class="comment">//或者所有参数拼接成一个参数,可以用特殊字段隔开,目的页面解析参数即可。</span></span><br><span class="line"><span class="comment">//避免出现 / 的转义问题</span></span><br><span class="line"><span class="language-xml"><span class="tag"><<span class="name">Route</span> <span class="attr">path</span>=<span class="string">"/a/:data*"</span> <span class="attr">component</span>=<span class="string">{a}/</span>></span></span></span><br></pre></td></tr></table></figure></li><li><p><em>跳转写法</em></p><p> 注意需要对参数编码,若参数中含有 <code>/</code> ,不编码导致多个参数截取错误</p> <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//link组件</span></span><br><span class="line"><<span class="title class_">Link</span> to={<span class="string">"/a/"</span> + <span class="built_in">encodeURIComponent</span>(data1) + <span class="string">"/"</span> + <span class="built_in">encodeURIComponent</span>(data2)}></<span class="title class_">Link</span>></span><br><span class="line"></span><br><span class="line"><span class="comment">//history</span></span><br><span class="line"><span class="variable language_">this</span>.<span class="property">props</span>.<span class="property">history</span>.<span class="title function_">push</span>(path)</span><br></pre></td></tr></table></figure></li><li><p><em>取值</em></p> <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="variable language_">this</span>.<span class="property">props</span>.<span class="property">match</span>.<span class="property">params</span>);</span><br><span class="line"><span class="comment">//为对象,可以获取参数,注意转义</span></span><br></pre></td></tr></table></figure></li></ol><h2 id="search"><a href="#search" class="headerlink" title="search"></a>search</h2><p>此种写法页面跳转参数在url上,且为 <code>?data1=1&data2=2</code> 的形式。</p><ol><li><p><em>路由写法</em></p> <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><<span class="title class_">Route</span> path=<span class="string">"/a"</span> component={a}/></span><br></pre></td></tr></table></figure></li><li><p><em>跳转写法</em></p> <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//link组件</span></span><br><span class="line"><<span class="title class_">Link</span> to={{</span><br><span class="line"> <span class="attr">pathname</span>: <span class="string">"/courses"</span>,</span><br><span class="line"> <span class="attr">search</span>: <span class="string">"?sort=name&hha=aa"</span>,</span><br><span class="line"> }}</span><br><span class="line">/></span><br><span class="line"></span><br><span class="line"><span class="comment">//history</span></span><br><span class="line"><span class="variable language_">this</span>.<span class="property">props</span>.<span class="property">history</span>.<span class="title function_">push</span>(path)</span><br></pre></td></tr></table></figure></li><li><p><em>取值</em></p> <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="variable language_">this</span>.<span class="property">props</span>.<span class="property">location</span>.<span class="property">search</span>);</span><br><span class="line"><span class="comment">//输出的值为一个字符串,不能区分出参数,需要自己解析处理参数</span></span><br></pre></td></tr></table></figure></li></ol><h2 id="state"><a href="#state" class="headerlink" title="state"></a>state</h2><p>此种写法页面跳转参数不在url上, 类似 <code>post</code> 提交。</p><ol><li><p><em>路由写法</em></p> <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><<span class="title class_">Route</span> path=<span class="string">"/a"</span> component={a}/></span><br></pre></td></tr></table></figure></li><li><p><em>跳转写法</em></p> <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//link组件</span></span><br><span class="line"><<span class="title class_">Link</span> to={{</span><br><span class="line"> <span class="attr">pathname</span>: <span class="string">"/courses"</span>,</span><br><span class="line"> <span class="attr">state</span>: {</span><br><span class="line"> <span class="attr">data1</span>: <span class="number">1</span>,</span><br><span class="line"> <span class="attr">data2</span>: <span class="number">2</span></span><br><span class="line"> },</span><br><span class="line"> }}</span><br><span class="line">/></span><br><span class="line"></span><br><span class="line"><span class="comment">//history</span></span><br><span class="line"><span class="variable language_">this</span>.<span class="property">props</span>.<span class="property">history</span>.<span class="title function_">push</span>(path)</span><br></pre></td></tr></table></figure></li><li><p><em>取值</em></p> <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="variable language_">this</span>.<span class="property">props</span>.<span class="property">location</span>.<span class="property">state</span>);</span><br><span class="line"><span class="comment">//为对象,可以获取参数</span></span><br></pre></td></tr></table></figure></li></ol><h2 id="注意"><a href="#注意" class="headerlink" title="注意"></a>注意</h2><p>页面重定向,直接传 location 对象,而不是 location.pathName, 否则造成参数丢失</p><p>this.props.history.push(this.props.history.location)</p>]]></content>
<categories>
<category> react </category>
</categories>
<tags>
<tag> react-router </tag>
<tag> 页面跳转 </tag>
</tags>
</entry>
<entry>
<title>react-css-loader</title>
<link href="/passages/react-css/"/>
<url>/passages/react-css/</url>
<content type="html"><![CDATA[<p><code>css-loader</code>,react 开发过程中解决全局污染问题。</p><span id="more"></span><h2 id="问题"><a href="#问题" class="headerlink" title="问题"></a>问题</h2><p>在 <code>create-react-app</code> 开发过程中, 出现 <code>css全局污染</code>。</p><h2 id="解决"><a href="#解决" class="headerlink" title="解决"></a>解决</h2><p><code>webpack</code> 处理过程中 的 <code>css-loader</code> 可以解决全局污染问题。</p><p>原理是最终页面渲染的类名变为自定义<code>字符串</code> 的形式。</p><h2 id="开启css-loader"><a href="#开启css-loader" class="headerlink" title="开启css-loader"></a>开启css-loader</h2><p>以 <code>webpack.config.dev.js</code> 说明 , <code>webpack.config.prod.js</code> 也需要改。</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">loader</span>: <span class="built_in">require</span>.<span class="title function_">resolve</span>(<span class="string">'css-loader'</span>),</span><br><span class="line"><span class="attr">options</span>: {</span><br><span class="line"> <span class="attr">importLoaders</span>: <span class="number">1</span>,</span><br><span class="line"> <span class="attr">modules</span>: <span class="literal">true</span>, <span class="comment">//新增,开启css-loader</span></span><br><span class="line"> <span class="attr">localIdentName</span>: <span class="string">'[name]__[local]__[hash:base64:5]'</span>, <span class="comment">//新增规则</span></span><br><span class="line">},</span><br></pre></td></tr></table></figure><p>页面所有样式失去效果,不要着急</p><p>注意事项:</p><ul><li>将 <code>import</code> 进来的 <code>./SomeComponent.css</code> 分配给一个本地常量.</li><li>在 <code>JSX</code> 中将 <code>className</code> 替换成的形式 <code>{styles.myClass}</code>. </li><li>需要修改 <code>CSS</code> 文件和 <code>JSX</code> 中的 <code>class</code> 名。因为 <code>CSS Modules</code> 不允许”-“出现在类名中。</li></ul><h2 id="关于ant-design冲突解决"><a href="#关于ant-design冲突解决" class="headerlink" title="关于ant-design冲突解决"></a>关于ant-design冲突解决</h2><p>按照上述改完之后,发现 ant-design 样式全部失效.</p><p><code>antd</code> 和 <code>css modules</code> 不能混用,针对 <code>antd</code> 的 <code>css</code> 单独写一条 <code>loader</code> 的规则, 不开启 <code>css modules</code></p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><span class="line">{</span><br><span class="line"> <span class="attr">test</span>: <span class="regexp">/\.css$/</span>,</span><br><span class="line"> <span class="attr">exclude</span>: <span class="regexp">/node_modules|antd\.css/</span>,</span><br><span class="line"> <span class="attr">use</span>: [</span><br><span class="line"> <span class="built_in">require</span>.<span class="title function_">resolve</span>(<span class="string">'style-loader'</span>),</span><br><span class="line"> {</span><br><span class="line"> <span class="attr">loader</span>: <span class="built_in">require</span>.<span class="title function_">resolve</span>(<span class="string">'css-loader'</span>),</span><br><span class="line"> <span class="attr">options</span>: {</span><br><span class="line"> <span class="attr">importLoaders</span>: <span class="number">1</span>,</span><br><span class="line"> <span class="attr">modules</span>: <span class="literal">true</span>,</span><br><span class="line"> <span class="attr">localIdentName</span>: <span class="string">'[name]__[local]__[hash:base64:5]'</span>,</span><br><span class="line"> },</span><br><span class="line"> },</span><br><span class="line"> </span><br><span class="line"> ],</span><br><span class="line">},</span><br><span class="line">{</span><br><span class="line"> <span class="attr">test</span>: <span class="regexp">/\.css$/</span>,</span><br><span class="line"> <span class="attr">include</span>: <span class="regexp">/node_modules|antd\.css/</span>,</span><br><span class="line"> <span class="attr">use</span>: [</span><br><span class="line"> <span class="built_in">require</span>.<span class="title function_">resolve</span>(<span class="string">'style-loader'</span>),</span><br><span class="line"> {</span><br><span class="line"> <span class="attr">loader</span>: <span class="built_in">require</span>.<span class="title function_">resolve</span>(<span class="string">'css-loader'</span>),</span><br><span class="line"> <span class="attr">options</span>: {</span><br><span class="line"> <span class="attr">importLoaders</span>: <span class="number">1</span></span><br><span class="line"> },</span><br><span class="line"> },</span><br><span class="line"> </span><br><span class="line"> ],</span><br><span class="line">},</span><br></pre></td></tr></table></figure><h2 id="CSS作用域相关"><a href="#CSS作用域相关" class="headerlink" title="CSS作用域相关"></a>CSS作用域相关</h2><ol><li><code>CSS Modules</code> 允许使用 <code>:global(.className)</code> 的语法,声明一个全局规则。凡是这样声明的class,都不会被编译成哈希字符串。</li><li><code>CSS Modules</code> 还提供一种显式的局部作用域语法 <code>:local(.className)</code>,等同于 <code>.className</code>.<br> 适用于解决对标签定义样式的问题,标签写样式,不经过 <code>localIdentName</code> 造成全局污染。修改为: <figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">:<span class="built_in">local</span>(.a){</span><br><span class="line"> <span class="selector-tag">tbody</span> <span class="selector-tag">tr</span> <span class="selector-tag">td</span> {</span><br><span class="line"> <span class="attribute">text-align</span>: center;</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure></li></ol><h2 id="ant-design实现按需加载"><a href="#ant-design实现按需加载" class="headerlink" title="ant-design实现按需加载"></a>ant-design实现按需加载</h2><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">{</span><br><span class="line"> <span class="attr">test</span>: <span class="regexp">/\.(js|jsx|mjs)$/</span>,</span><br><span class="line"> <span class="attr">include</span>: paths.<span class="property">appSrc</span>,</span><br><span class="line"> <span class="attr">loader</span>: <span class="built_in">require</span>.<span class="title function_">resolve</span>(<span class="string">'babel-loader'</span>),</span><br><span class="line"> <span class="attr">options</span>: {</span><br><span class="line"> <span class="attr">plugins</span>: [ <span class="comment">//按需加载</span></span><br><span class="line"> [<span class="string">'import'</span>, { <span class="attr">libraryName</span>: <span class="string">'antd'</span>, <span class="attr">style</span>: <span class="string">'css'</span> }]</span><br><span class="line"> ],</span><br><span class="line"> <span class="comment">// This is a feature of `babel-loader` for webpack (not Babel itself).</span></span><br><span class="line"> <span class="comment">// It enables caching results in ./node_modules/.cache/babel-loader/</span></span><br><span class="line"> <span class="comment">// directory for faster rebuilds.</span></span><br><span class="line"> <span class="attr">cacheDirectory</span>: <span class="literal">true</span>,</span><br><span class="line"></span><br><span class="line"> },</span><br><span class="line">},</span><br></pre></td></tr></table></figure>]]></content>
<categories>
<category> react </category>
</categories>
<tags>
<tag> webpack </tag>
<tag> create-react-app </tag>
<tag> css-loader/antd </tag>
</tags>
</entry>
<entry>
<title>axios请求之异步处理</title>
<link href="/passages/es6-async/"/>
<url>/passages/es6-async/</url>
<content type="html"><![CDATA[<p>使用 <code>axios</code> 关于异步请求的处理。</p><span id="more"></span><h2 id="axios"><a href="#axios" class="headerlink" title="axios"></a>axios</h2><p><a href="https://www.kancloud.cn/yunye/axios/234845">官网</a></p><h2 id="异步处理"><a href="#异步处理" class="headerlink" title="异步处理"></a>异步处理</h2><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//返回了一个promise对象</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">request</span>(<span class="params">url, params</span>) {</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">Promise</span>(<span class="function">(<span class="params">resolve, reject</span>) =></span> {</span><br><span class="line"> axios.<span class="title function_">get</span>(url, {</span><br><span class="line"> <span class="attr">params</span>: params</span><br><span class="line"> })</span><br><span class="line"> .<span class="title function_">then</span>(<span class="function">(<span class="params">res</span>) =></span> {</span><br><span class="line"> <span class="title function_">resolve</span>(res); </span><br><span class="line"> })</span><br><span class="line"> })</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">//async 异步函数</span></span><br><span class="line"><span class="comment">//await后面是一个Promise对象,用来等待Promise对象状态被resolved</span></span><br><span class="line"><span class="comment">//如果await的是Promise对象会造成异步函数停止执行并且等待Promise的解决</span></span><br><span class="line"><span class="keyword">async</span> <span class="title function_">getData</span>(<span class="params"></span>) {</span><br><span class="line"> <span class="keyword">let</span> res = <span class="keyword">await</span> <span class="title function_">request</span>(<span class="string">'url'</span>, <span class="string">'data'</span>);</span><br><span class="line"> consoel.<span class="title function_">log</span>(res); </span><br><span class="line">}</span><br><span class="line"></span><br></pre></td></tr></table></figure><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//axios返回的就是一个Promise对象,此函数返回。</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">request</span>(<span class="params">url, params</span>) {</span><br><span class="line"> <span class="keyword">return</span> axios.<span class="title function_">get</span>(url, {</span><br><span class="line"> <span class="attr">params</span>: params</span><br><span class="line"> })</span><br><span class="line"> .<span class="title function_">then</span>(<span class="keyword">function</span> (<span class="params">response</span>) {</span><br><span class="line"> <span class="keyword">return</span> response</span><br><span class="line"> })</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">//需要在then方法里回调</span></span><br><span class="line"><span class="title function_">request</span>(<span class="string">'url'</span>, {})</span><br><span class="line"> .<span class="title function_">then</span>(<span class="keyword">function</span> (<span class="params">response</span>) {</span><br><span class="line"> <span class="variable language_">console</span>.<span class="title function_">log</span>(response);</span><br><span class="line"> })</span><br></pre></td></tr></table></figure>]]></content>
<categories>
<category> 请求 </category>
</categories>
<tags>
<tag> axios </tag>
<tag> es6 promise/async/await </tag>
</tags>
</entry>
<entry>
<title>Gulp && Grunt</title>
<link href="/passages/gulp&grunt/"/>
<url>/passages/gulp&grunt/</url>
<content type="html"><![CDATA[<p><code>Gulp</code> 与 <code>Grunt</code> 简单介绍</p><span id="more"></span><h1 id="gulp"><a href="#gulp" class="headerlink" title="gulp"></a>gulp</h1><p>用自动化构建工具增强你的工作流程!</p><ul><li><code>易于使用</code>,通过代码优于配置的策略,Gulp 让简单的任务简单,复杂的任务可管理。</li><li><code>构建快速</code>,利用 Node.js 流的威力,你可以快速构建项目并减少频繁的 IO 操作。</li><li><code>插件高质</code>,Gulp 严格的插件指南确保插件如你期望的那样简洁高质得工作。</li><li><code>易于学习</code>,通过最少的 API,掌握 Gulp 毫不费力,构建工作尽在掌握:如同一系列流管道。</li></ul><h2 id="安装"><a href="#安装" class="headerlink" title="安装"></a>安装</h2><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">npm install gulp -g <span class="comment">//全局安装</span></span><br><span class="line">npm install --save-dev gulp <span class="comment">//作为项目开发依赖安装</span></span><br></pre></td></tr></table></figure><h2 id="gulpfile-js"><a href="#gulpfile-js" class="headerlink" title="gulpfile.js"></a>gulpfile.js</h2><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> gulp = <span class="built_in">require</span>(<span class="string">'gulp'</span>);</span><br><span class="line">gulp.<span class="title function_">task</span>(<span class="string">'default'</span>, <span class="keyword">function</span>(<span class="params"></span>) {</span><br><span class="line"> <span class="comment">// 将你的默认的任务代码放在这</span></span><br><span class="line">});</span><br></pre></td></tr></table></figure><h2 id="运行"><a href="#运行" class="headerlink" title="运行"></a>运行</h2><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">gulp <span class="comment">//默认执行default任务</span></span><br><span class="line"><span class="comment">//手动指定一个 gulpfile 的路径,这在你有很多个 gulpfile 的时候很有用</span></span><br><span class="line">gulp --gulpfile <gulpfile path> </span><br></pre></td></tr></table></figure><p>Task 可以通过 <code>gulp <task> <othertask></code> 方式来执行。如果只运行 <code>gulp</code> 命令,则会执行所注册的名为 <code>default</code> 的 task,如果没有这个 task,那么 gulp 会报错。</p><h2 id="gulp与grunt区别"><a href="#gulp与grunt区别" class="headerlink" title="gulp与grunt区别"></a>gulp与grunt区别</h2><p><code>Grunt</code> 主要是以文件为媒介来运行它的工作流的,比如在Grunt中执行完一项任务后,会把结果写入到一个临时文件中,然后可以在这个临时文件内容的基础上执行其它任务,执行完成后又把结果写入到临时文件中,然后又以这个为基础继续执行其它任务…就这样反复下去。</p><p>而在<code>Gulp</code>中,使用的是Nodejs中的stream(流),首先获取到需要的stream,然后可以通过stream的 <code>pipe()</code> 方法把流导入到你想要的地方,比如Gulp的插件中,经过插件处理后的流又可以继续导入到其他插件中,当然也可以把流写入到文件中。所以Gulp是以stream为媒介的,它不需要频繁的生成临时文件,这也是Gulp的速度比Grunt快的一个原因。</p><h2 id="API介绍"><a href="#API介绍" class="headerlink" title="API介绍"></a>API介绍</h2><p>掌握四个API即可</p><ul><li><code>gulp.task()</code> //定义一个使用 Orchestrator 实现的任务(task)。</li><li><code>gulp.src()</code> //输出(Emits)符合所提供的匹配模式(glob)或者匹配模式的数组(array of globs)的文件。</li><li><code>gulp.dest()</code> //能被 pipe 进来,并且将会写文件。并且重新输出(emits)所有数据,因此你可以将它 pipe 到多个文件夹。如果某文件夹不存在,将会自动创建它。</li><li><code>gulp.watch()</code> //监视文件,并且可以在文件发生改动时候做一些事情。它总会返回一个 EventEmitter 来发射(emit) change 事件。</li></ul><h1 id="grunt"><a href="#grunt" class="headerlink" title="grunt"></a>grunt</h1><p><code>Grunt</code>是 <strong>JavaScript</strong> 世界的构建工具。</p><h2 id="为什么要用grunt?"><a href="#为什么要用grunt?" class="headerlink" title="为什么要用grunt?"></a>为什么要用<code>grunt</code>?</h2><p><code>Grunt</code> 生态系统非常庞大,并且一直在增长。由于拥有数量庞大的插件可供选择,因此,你可以利用 Grunt 自动完成任何事,并且花费最少的代价,只要配置好 <code>Gruntfile</code> 文件, 就可以实现自动执行。</p><p>每次运行 <code>grunt</code> 时,他就利用 <code>node</code> 提供的 <code>require()</code> 系统查找本地安装的 <code>Grunt</code>。正是由于这一机制,你可以在项目的任意子目录中运行<code>grunt</code> 。如果找到一份本地安装的 <code>Grunt</code> ,<code>CLI</code> 就将其加载,并传递<code>Gruntfile</code> 中的配置信息,然后执行你所指定的任务。</p><h2 id="安装-1"><a href="#安装-1" class="headerlink" title="安装"></a>安装</h2><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">npm install -g grunt-cli <span class="comment">//全局安装</span></span><br><span class="line"><span class="comment">//Grunt CLI的任务很简单:调用与Gruntfile在同一目录中的Grunt,</span></span><br><span class="line"><span class="comment">//这样带来的好处是,允许你在同一个系统上同时安装多个版本的 Grunt。</span></span><br></pre></td></tr></table></figure><h2 id="Gruntfile"><a href="#Gruntfile" class="headerlink" title="Gruntfile"></a>Gruntfile</h2><p><code>Gruntfile</code>主要有以下几个模块组成。</p><ul><li>“wrapper” 函数</li><li>项目与任务配置</li><li>加载grunt插件和任务</li><li>自定义任务</li></ul><h2 id="wrapper函数"><a href="#wrapper函数" class="headerlink" title="wrapper函数"></a>wrapper函数</h2><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="variable language_">module</span>.<span class="property">exports</span> = <span class="keyword">function</span>(<span class="params">grunt</span>) {</span><br><span class="line"> <span class="comment">// Do grunt-related things in here</span></span><br><span class="line">};</span><br></pre></td></tr></table></figure><h2 id="项目和任务配置"><a href="#项目和任务配置" class="headerlink" title="项目和任务配置"></a>项目和任务配置</h2><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">grunt.<span class="title function_">initConfig</span>({</span><br><span class="line">});</span><br></pre></td></tr></table></figure><h2 id="加载插件和任务"><a href="#加载插件和任务" class="headerlink" title="加载插件和任务"></a>加载插件和任务</h2><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 加载能够提供"uglify"任务的插件。</span></span><br><span class="line">grunt.<span class="title function_">loadNpmTasks</span>(<span class="string">'grunt-contrib-uglify'</span>);</span><br></pre></td></tr></table></figure><h2 id="自定义任务"><a href="#自定义任务" class="headerlink" title="自定义任务"></a>自定义任务</h2><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// Default task(s),可添加执行多个任务</span></span><br><span class="line">grunt.<span class="title function_">registerTask</span>(<span class="string">'default'</span>, [<span class="string">'uglify'</span>]);</span><br></pre></td></tr></table></figure><h2 id="Grunt配置"><a href="#Grunt配置" class="headerlink" title="Grunt配置"></a>Grunt配置</h2><p><code>Grunt</code> 的 <code>task</code> 配置都是在 <code>Gruntfile</code> 中的 <code>grunt.initConfig</code> 方法中指定的。</p><p>此配置主要是以任务名称命名的属性,也可以包含其他任意数据。一旦这些代表任意数据的属性与任务所需要的属性相冲突,就将被忽略。</p>]]></content>
<categories>
<category> 打包工具 </category>
</categories>
<tags>
<tag> gulp </tag>
<tag> grunt </tag>
</tags>
</entry>
<entry>
<title>log4js</title>
<link href="/passages/log4js/"/>
<url>/passages/log4js/</url>
<content type="html"><![CDATA[<p><code>log4js</code> 简单知识</p><span id="more"></span><h1 id="说明"><a href="#说明" class="headerlink" title="说明"></a>说明</h1><p>日常开发中,对于日志模块,<code>java</code>开发 -> <code>log4j</code>,而 <code>nodejs</code>开发,则对应工具为 <code>log4js</code>。</p><h1 id="log4js-介绍"><a href="#log4js-介绍" class="headerlink" title="log4js 介绍"></a><em>log4js</em> 介绍</h1><h2 id="安装"><a href="#安装" class="headerlink" title="安装"></a>安装</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm install log4js --save</span><br></pre></td></tr></table></figure><h2 id="日志级别"><a href="#日志级别" class="headerlink" title="日志级别"></a>日志级别</h2><blockquote><p> 等级由低到高:trace < debug < info < warn < Error < Fatal;</p></blockquote><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">logger.<span class="title function_">trace</span>(<span class="string">'Entering cheese testing'</span>);</span><br><span class="line">logger.<span class="title function_">debug</span>(<span class="string">'Got cheese.'</span>);</span><br><span class="line">logger.<span class="title function_">info</span>(<span class="string">'Cheese is Gouda.'</span>);</span><br><span class="line">logger.<span class="title function_">warn</span>(<span class="string">'Cheese is quite smelly.'</span>);</span><br><span class="line">logger.<span class="title function_">error</span>(<span class="string">'Cheese is too ripe!'</span>);</span><br><span class="line">logger.<span class="title function_">fatal</span>(<span class="string">'Cheese was breeding ground for listeria.'</span>);</span><br></pre></td></tr></table></figure><ul><li>debug 可以随意的使用于任何觉得有利于在调试时更详细的了解系统运行状态的东东;</li><li>info 重要,输出信息:用来反馈系统的当前状态给最终用户的;</li><li>warn, 可修复,系统可继续运行下去;</li><li>Error, 可修复性,但无法确定系统会正常的工作下去;</li><li>Fatal, 相当严重,可以肯定这种错误已经无法修复,并且如果系统继续运行下去的话后果严重。</li></ul><h2 id="函数"><a href="#函数" class="headerlink" title="函数"></a>函数</h2><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="title function_">getLogger</span>(<span class="string">"参数"</span>) <span class="comment">//追踪产生此日志的文件.</span></span><br><span class="line"></span><br><span class="line">log4js.<span class="title function_">configure</span>(log4jsConfig); <span class="comment">//设置配置项</span></span><br></pre></td></tr></table></figure><h2 id="配置项"><a href="#配置项" class="headerlink" title="配置项"></a>配置项</h2><figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">"log4jsConfig"</span><span class="punctuation">:</span> <span class="punctuation">{</span></span><br><span class="line"> <span class="attr">"appenders"</span><span class="punctuation">:</span> <span class="punctuation">[</span></span><br><span class="line"> <span class="punctuation">{</span></span><br><span class="line"> <span class="attr">"type"</span><span class="punctuation">:</span> <span class="string">"console"</span></span><br><span class="line"> <span class="punctuation">}</span><span class="punctuation">,</span></span><br><span class="line"> <span class="punctuation">{</span></span><br><span class="line"> <span class="attr">"type"</span><span class="punctuation">:</span> <span class="string">"file"</span><span class="punctuation">,</span> </span><br><span class="line"> <span class="attr">"absolute"</span><span class="punctuation">:</span> <span class="keyword">true</span><span class="punctuation">,</span> <span class="comment">//绝对路径</span></span><br><span class="line"> <span class="attr">"filename"</span><span class="punctuation">:</span> <span class="string">"a.log"</span><span class="punctuation">,</span> <span class="comment">//存放日志文件的目录和文件名</span></span><br><span class="line"> <span class="attr">"maxLogSize"</span><span class="punctuation">:</span> <span class="number">10000000</span><span class="punctuation">,</span> <span class="comment">//每个日志文件大小</span></span><br><span class="line"> <span class="attr">"backups"</span><span class="punctuation">:</span> <span class="number">100</span><span class="punctuation">,</span> <span class="comment">//备份文件的数量,超过会被删除</span></span><br><span class="line"> <span class="attr">"category"</span><span class="punctuation">:</span> <span class="string">"http"</span> <span class="comment">//日志策略,类别,与级别不同的一个维度</span></span><br><span class="line"> <span class="punctuation">}</span><span class="punctuation">,</span></span><br><span class="line"> <span class="punctuation">]</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"levels"</span><span class="punctuation">:</span> <span class="punctuation">{</span></span><br><span class="line"> <span class="attr">"[all]"</span><span class="punctuation">:</span> <span class="string">"INFO"</span> <span class="comment">//设置日志级别,只打印info级别及以上级别的</span></span><br><span class="line"> <span class="punctuation">}</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"replaceConsole"</span><span class="punctuation">:</span> <span class="keyword">true</span> <span class="comment">//替换掉原来自带的console, 自带的没有颜色区分</span></span><br><span class="line"> <span class="punctuation">}</span><span class="punctuation">,</span></span><br></pre></td></tr></table></figure><h2 id="记录请求"><a href="#记录请求" class="headerlink" title="记录请求"></a>记录请求</h2><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//app.js</span></span><br><span class="line"></span><br><span class="line">app.<span class="title function_">use</span>(log4js.<span class="title function_">connectLogger</span>(log4js.<span class="title function_">getLogger</span>(<span class="string">"http"</span>), {</span><br><span class="line"> <span class="attr">level</span>: <span class="string">'auto'</span>,</span><br><span class="line"> <span class="attr">format</span>: <span class="string">':remote-addr - -'</span> + <span class="string">' ":method :url HTTP/:http-version"'</span> + <span class="string">' :status :content-length :response-time ":referrer"'</span> + <span class="string">' ":user-agent"'</span></span><br><span class="line">}));</span><br><span class="line"></span><br></pre></td></tr></table></figure><p>日志的一个重要功能不仅仅是在调试时使用,最重要的还是当前端发起请求时,能把该请求记录在日志中,该行代码的作用就是这个功能。</p><p>其中的level参数表示日志输出级别,设置为auto,日志级别对应规则为:</p><ul><li>http返回码为3**:level=WARN;</li><li>http返回码为4<strong>,5</strong>时,level=ERROR;</li><li>其他的返回码,level=INFO</li></ul><h1 id="日志分片"><a href="#日志分片" class="headerlink" title="日志分片"></a>日志分片</h1><h2 id="按文件大小"><a href="#按文件大小" class="headerlink" title="按文件大小"></a>按文件大小</h2><figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">"log4jsConfig"</span><span class="punctuation">:</span> <span class="punctuation">{</span></span><br><span class="line"> <span class="attr">"appenders"</span><span class="punctuation">:</span> <span class="punctuation">[</span></span><br><span class="line"> <span class="punctuation">{</span></span><br><span class="line"> <span class="attr">"type"</span><span class="punctuation">:</span> <span class="string">"console"</span></span><br><span class="line"> <span class="punctuation">}</span><span class="punctuation">,</span></span><br><span class="line"> <span class="punctuation">{</span></span><br><span class="line"> <span class="attr">"type"</span><span class="punctuation">:</span> <span class="string">"file"</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"absolute"</span><span class="punctuation">:</span> <span class="keyword">true</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"filename"</span><span class="punctuation">:</span> <span class="string">"a.log"</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"maxLogSize"</span><span class="punctuation">:</span> <span class="number">10</span><span class="punctuation">,</span> <span class="comment">//单位应该是字节,设置 10000000 ,基本是10兆左右</span></span><br><span class="line"> <span class="attr">"backups"</span><span class="punctuation">:</span> <span class="number">5</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"category"</span><span class="punctuation">:</span> <span class="string">"http"</span></span><br><span class="line"> <span class="punctuation">}</span></span><br><span class="line"> <span class="punctuation">]</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"levels"</span><span class="punctuation">:</span> <span class="punctuation">{</span></span><br><span class="line"> <span class="attr">"[all]"</span><span class="punctuation">:</span> <span class="string">"DEBUG"</span></span><br><span class="line"> <span class="punctuation">}</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"replaceConsole"</span><span class="punctuation">:</span> <span class="keyword">true</span></span><br><span class="line"> <span class="punctuation">}</span><span class="punctuation">,</span></span><br></pre></td></tr></table></figure><h2 id="对应效果"><a href="#对应效果" class="headerlink" title="对应效果"></a>对应效果</h2><p>只能备份 <code>backups</code> 指定的份数,最新的会更新删除替换, 且每个文件为 <code>maxLogSize</code>的值。</p><h2 id="按日期分片"><a href="#按日期分片" class="headerlink" title="按日期分片"></a>按日期分片</h2><figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">"log4jsConfig"</span><span class="punctuation">:</span> <span class="punctuation">{</span></span><br><span class="line"> <span class="attr">"appenders"</span><span class="punctuation">:</span> <span class="punctuation">[</span></span><br><span class="line"> <span class="punctuation">{</span></span><br><span class="line"> <span class="attr">"type"</span><span class="punctuation">:</span> <span class="string">"console"</span></span><br><span class="line"> <span class="punctuation">}</span><span class="punctuation">,</span></span><br><span class="line"> <span class="punctuation">{</span></span><br><span class="line"> <span class="attr">"type"</span><span class="punctuation">:</span> <span class="string">"dateFile"</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"absolute"</span><span class="punctuation">:</span> <span class="keyword">true</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"filename"</span><span class="punctuation">:</span> <span class="string">"a-accesslog"</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"pattern"</span><span class="punctuation">:</span> <span class="string">"-yyyy-MM-dd.log"</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"alwaysIncludePattern"</span> <span class="punctuation">:</span> <span class="keyword">true</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"category"</span><span class="punctuation">:</span> <span class="string">"http"</span></span><br><span class="line"> <span class="punctuation">}</span></span><br><span class="line"> <span class="punctuation">]</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"levels"</span><span class="punctuation">:</span> <span class="punctuation">{</span></span><br><span class="line"> <span class="attr">"[all]"</span><span class="punctuation">:</span> <span class="string">"DEBUG"</span></span><br><span class="line"> <span class="punctuation">}</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"replaceConsole"</span><span class="punctuation">:</span> <span class="keyword">true</span></span><br><span class="line"> <span class="punctuation">}</span><span class="punctuation">,</span></span><br></pre></td></tr></table></figure><h2 id="对应效果-1"><a href="#对应效果-1" class="headerlink" title="对应效果"></a>对应效果</h2><p>日志按照日期进行分片,且不会限制大小。</p>]]></content>
<categories>
<category> 日志 </category>
</categories>
<tags>
<tag> 日志 </tag>
<tag> log4js </tag>
</tags>
</entry>