-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathatom.xml
1554 lines (1488 loc) · 92.3 KB
/
atom.xml
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"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<id>https://0520.eu.org</id>
<title>O52O</title>
<updated>2024-11-10T02:16:19.168Z</updated>
<generator>https://github.com/jpmonette/feed</generator>
<link rel="alternate" href="https://0520.eu.org"/>
<link rel="self" href="https://0520.eu.org/atom.xml"/>
<logo>https://0520.eu.org/images/avatar.png</logo>
<icon>https://0520.eu.org/favicon.ico</icon>
<rights>All rights reserved 2024, O52O</rights>
<entry>
<title type="html"><![CDATA[免费注册US.KG域名:从身份生成到Cloudflare托管的全流程指南]]></title>
<id>https://0520.eu.org/post/us-kg/</id>
<link href="https://0520.eu.org/post/us-kg/">
</link>
<updated>2024-09-13T08:15:55.000Z</updated>
<summary type="html"><![CDATA[<p>本文详细介绍了如何免费注册us.kg域名并将其托管到Cloudflare的完整过程。主要步骤包括:</p>
<ol>
<li>使用在线工具生成身份信息</li>
<li>在nic.us.kg注册账户</li>
<li>完成KYC验证</li>
<li>申请us.kg域名</li>
<li>在Cloudflare上设置DNS<br>
通过遵循本指南,读者可以轻松获得一个免费的us.kg域名,并利用Cloudflare的强大功能进行管理。文章还包含了申请中文域名时需要使用域名转码工具的提示。</li>
</ol>
<p>对于想要快速搭建个人网站或在线项目的用户来说,这是一个经济实惠的选择。然而,用户应注意遵守相关法律法规,并谨慎使用生成的身份信息。</p>
]]></summary>
<content type="html"><;
</code></pre>
<p><img src="https://0520.eu.org/post-images/1726215534402.png" alt="" loading="lazy"><br>
<img src="https://0520.eu.org/post-images/1726215540531.png" alt="" loading="lazy"><br>
<img src="https://0520.eu.org/post-images/1726215547712.png" alt="" loading="lazy"></p>
<pre><code>### 2. 选择**KYC方式:Upload KYC Document(Not Recommended & Legacy)**;
</code></pre>
<figure data-type="image" tabindex="3"><img src="https://0520.eu.org/post-images/1726215564816.png" alt="" loading="lazy"></figure>
<pre><code>* 点击Proceed to Default Server (Click me to redirect KYC Page)进入下一步;
* 填写KYC信息
* Why register the .US.KG domain name:填入blog;
* Document Type:填入proof of address;
* KYC Document:选择第一步保存的kyc.png文件;
</code></pre>
<figure data-type="image" tabindex="4"><img src="https://0520.eu.org/post-images/1726215575194.png" alt="" loading="lazy"></figure>
<pre><code>* 点击Submit等待提示Successful!,及实名审核完成;
</code></pre>
<figure data-type="image" tabindex="5"><img src="https://0520.eu.org/post-images/1726215584062.png" alt="" loading="lazy"></figure>
<pre><code>* 重新进行us.kg账户登录即可。
</code></pre>
<h2 id="申请uskg域名">申请us.kg域名</h2>
<h3 id="1点击domain-name-registration申请你的uskg域名">1.点击Domain name registration申请你的us.kg域名;</h3>
<figure data-type="image" tabindex="6"><img src="https://0520.eu.org/post-images/1726215596030.png" alt="" loading="lazy"></figure>
<h3 id="2-输入你想注册的域名后点击check">2. 输入你想注册的域名后,点击Check;</h3>
<p><img src="https://0520.eu.org/post-images/1726215604993.png" alt="" loading="lazy"><br>
<img src="https://0520.eu.org/post-images/1726215613220.png" alt="" loading="lazy"></p>
<h3 id="3前往cloudflare添加你的域名">3.前往Cloudflare添加你的域名;</h3>
<figure data-type="image" tabindex="7"><img src="https://0520.eu.org/post-images/1726215620763.png" alt="" loading="lazy"></figure>
<h3 id="4选择free套餐后点继续">4.选择Free套餐后,点继续;</h3>
<figure data-type="image" tabindex="8"><img src="https://0520.eu.org/post-images/1726215628229.png" alt="" loading="lazy"></figure>
<h3 id="5等扫描结束">5.等扫描结束</h3>
<figure data-type="image" tabindex="9"><img src="https://0520.eu.org/post-images/1726215635510.png" alt="" loading="lazy"></figure>
<h3 id="6点击继续前往激活">6.点击继续前往激活</h3>
<p><img src="https://0520.eu.org/post-images/1726215642376.png" alt="" loading="lazy"><br>
<img src="https://0520.eu.org/post-images/1726215647986.png" alt="" loading="lazy"></p>
<h3 id="7复制cloudflare提供的ns信息填入uskg对应name-server-1name-server-2">7.复制Cloudflare提供的NS信息填入us.kg对应Name Server 1&Name Server 2</h3>
<p><img src="https://0520.eu.org/post-images/1726215656709.png" alt="" loading="lazy"><br>
<img src="https://0520.eu.org/post-images/1726215666338.png" alt="" loading="lazy"></p>
<h3 id="8点击-继续-register-后等待域名生效">8.点击 继续 & Register! 后等待域名生效;</h3>
<p><img src="https://0520.eu.org/post-images/1726215675212.png" alt="" loading="lazy"><br>
<img src="https://0520.eu.org/post-images/1726215682070.png" alt="" loading="lazy"></p>
<h1 id="彩蛋申请中文域名需要中文域名转码">彩蛋:申请中文域名需要<a href="https://defense.yunaq.com/tools/dnstranscoding/">中文域名转码</a></h1>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[搭建Rin博客笔记]]></title>
<id>https://0520.eu.org/post/rin-blog/</id>
<link href="https://0520.eu.org/post/rin-blog/">
</link>
<updated>2024-09-11T08:32:52.000Z</updated>
<summary type="html"><![CDATA[<p>构建命令:bun b<br>
构建输出目录:client/dist</p>
<p>环境变量:<br>
NAME=Xeu # 昵称,显示在左上角<br>
DESCRIPTION=杂食动物 # 个人描述,显示在左上角昵称下方<br>
AVATAR=https://avatars.githubusercontent.com/u/36541432 # 头像地址,显示在左上角<br>
API_URL=https://rin.xeu.life # 服务端域名,可以先使用默认值查看效果,后续部署服务端后再修改<br>
PAGE_SIZE=5 # 默认分页大小,推荐 5<br>
SKIP_DEPENDENCY_INSTALL=true<br>
UNSTABLE_PRE_BUILD=asdf install bun latest && asdf global bun latest && bun i</p>
]]></summary>
<content type="html"><![CDATA[<p>构建命令:bun b<br>
构建输出目录:client/dist</p>
<p>环境变量:<br>
NAME=Xeu # 昵称,显示在左上角<br>
DESCRIPTION=杂食动物 # 个人描述,显示在左上角昵称下方<br>
AVATAR=https://avatars.githubusercontent.com/u/36541432 # 头像地址,显示在左上角<br>
API_URL=https://rin.xeu.life # 服务端域名,可以先使用默认值查看效果,后续部署服务端后再修改<br>
PAGE_SIZE=5 # 默认分页大小,推荐 5<br>
SKIP_DEPENDENCY_INSTALL=true<br>
UNSTABLE_PRE_BUILD=asdf install bun latest && asdf global bun latest && bun i</p>
<!-- more -->
<p>存储桶设置cros策略设置:</p>
<pre><code class="language-json">[
{
"AllowedOrigins": [
"https://bucket.kjzxs.site"
],
"AllowedMethods": [
"GET",
"DELETE",
"HEAD",
"POST",
"PUT"
],
"AllowedHeaders": [
"Content-Type"
]
}
]
</code></pre>
<p>访问以下连接接入github验证<br>
https://github.com/settings/developers</p>
<p>接入github:<br>
Homepage URL 填写上面的前端地址<br>
Authorization callback URL 填写 https://<你的后端地址>/user/github/callback</p>
<p>仓库变量:<br>
FRONTEND_URL=前端地址,填写上文前端所绑定的域名,如 https://blog.obdo.cc<br>
S3_BUCKET=R2 存储桶名称,如上文示例中的 rin-storage<br>
S3_REGION=auto<br>
S3_ENDPOINT=R2 的 S3 API,去掉域名后面的路径,如 https://1234567890abcdef1234567890abcd.r2.cloudflarestorage.com<br>
S3_ACCESS_HOST=R2 公开访问域名,如上文示例中的 https://rin-storage.obdo.cc</p>
<p>仓库secret:<br>
CLOUDFLARE_ACCOUNT_ID=Cloudflare 的 账户ID<br>
CLOUDFLARE_API_TOKEN=Cloudflare 的 用户API令牌 值<br>
RIN_GITHUB_CLIENT_ID=上文生成的 Github Client ID<br>
RIN_GITHUB_CLIENT_SECRET=上文生成的 Github Client Secret<br>
JWT_SECRET=加密用的密钥,你可以使用密码生成器随机生成一个<br>
S3_ACCESS_KEY_ID=存储桶API的 访问密钥ID<br>
S3_SECRET_ACCESS_KEY=存储桶API的 机密访问密钥</p>
<p>添加路由:<br>
点击 添加自定义域,绑定自己的后端域名<br>
点击 添加路由,依次加入 前端域名/sub/* 前端域名/seo/*</p>
<p>回到前面创建的前端 Pages 设置<br>
将 制作 与 预览 的 APL_URL 均修改为后端域名</p>
<p>最后重新部署pages</p>
<p>访问以下连接接入github验证<br>
https://github.com/settings/developers</p>
<p>秘钥生成器地址:<br>
https://www.avast.com/random-password-generator</p>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[CF-Workers-docker.io:Docker仓库镜像代理工具]]></title>
<id>https://0520.eu.org/post/cf-workers-docker/</id>
<link href="https://0520.eu.org/post/cf-workers-docker/">
</link>
<updated>2024-06-24T13:48:17.000Z</updated>
<summary type="html"><![CDATA[<p><a href="https://github.com/cmliu/CF-Workers-docker.io?tab=readme-ov-file#%E7%AC%AC%E4%B8%89%E6%96%B9-dockerhub-%E9%95%9C%E5%83%8F%E6%9C%8D%E5%8A%A1"><strong>第三方 DockerHub 镜像服务列表</strong></a></p>
<h1 id="cf-workers-dockeriodocker仓库镜像代理工具">CF-Workers-docker.io:Docker仓库镜像代理工具</h1>
<p>这个项目是一个基于 Cloudflare Workers 的 Docker 镜像代理工具。它能够中转对 Docker 官方镜像仓库的请求,解决一些访问限制和加速访问的问题。</p>
]]></summary>
<content type="html"><![CDATA[<p><a href="https://github.com/cmliu/CF-Workers-docker.io?tab=readme-ov-file#%E7%AC%AC%E4%B8%89%E6%96%B9-dockerhub-%E9%95%9C%E5%83%8F%E6%9C%8D%E5%8A%A1"><strong>第三方 DockerHub 镜像服务列表</strong></a></p>
<h1 id="cf-workers-dockeriodocker仓库镜像代理工具">CF-Workers-docker.io:Docker仓库镜像代理工具</h1>
<p>这个项目是一个基于 Cloudflare Workers 的 Docker 镜像代理工具。它能够中转对 Docker 官方镜像仓库的请求,解决一些访问限制和加速访问的问题。</p>
<!-- more -->
<h2 id="部署方式">部署方式</h2>
<ul>
<li><strong>Workers</strong> 部署:复制 <a href="https://github.com/cmliu/CF-Workers-docker.io/blob/main/_worker.js">_worker.js</a> 代码,<code>保存并部署</code>即可</li>
<li><strong>Pages</strong> 部署:<code>Fork</code> 后 <code>连接GitHub</code> 一键部署即可</li>
</ul>
<h2 id="如何使用">如何使用?</h2>
<p>例如您的Workers项目域名为:<code>docker.fxxk.dedyn.io</code>;</p>
<h3 id="1官方镜像路径前面加域名">1.官方镜像路径前面加域名</h3>
<pre><code class="language-shell">docker pull docker.fxxk.dedyn.io/stilleshan/frpc:latest
</code></pre>
<pre><code class="language-shell">docker pull docker.fxxk.dedyn.io/library/nginx:stable-alpine3.19-perl
</code></pre>
<h3 id="2一键设置镜像加速">2.一键设置镜像加速</h3>
<p>修改文件 <code>/etc/docker/daemon.json</code>(如果不存在则创建)</p>
<pre><code class="language-shell">sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://docker.fxxk.dedyn.io"] # 请替换为您自己的Worker自定义域名
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
</code></pre>
<h2 id="变量说明">变量说明</h2>
<table>
<thead>
<tr>
<th>变量名</th>
<th>示例</th>
<th>必填</th>
<th>备注</th>
</tr>
</thead>
<tbody>
<tr>
<td>URL302</td>
<td>https://t.me/CMLiussss</td>
<td>❌</td>
<td>主页302跳转</td>
</tr>
<tr>
<td>URL</td>
<td>https://www.baidu.com/</td>
<td>❌</td>
<td>主页伪装(设为<code>nginx</code>则伪装为nginx默认页面)</td>
</tr>
</tbody>
</table>
<h1 id="第三方-dockerhub-镜像服务">第三方 DockerHub 镜像服务</h1>
<p><strong>注意:</strong></p>
<ul>
<li>以下内容仅做镜像服务的整理与搜集,未做任何安全性检测和验证。</li>
<li>使用前请自行斟酌,并根据实际需求进行必要的安全审查。</li>
<li>本列表中的任何服务都不做任何形式的安全承诺或保证。</li>
</ul>
<table>
<thead>
<tr>
<th>DockerHub 镜像仓库</th>
<th>镜像加地址</th>
</tr>
</thead>
<tbody>
<tr>
<td><a href="https://t.me/bestcfipas/1900">bestcfipas镜像服务</a></td>
<td><code>https://docker.registry.cyou</code></td>
</tr>
<tr>
<td></td>
<td><code>https://docker-cf.registry.cyou</code></td>
</tr>
<tr>
<td><a href="https://t.me/zero_free/80">zero_free镜像服务</a></td>
<td><code>https://docker.jsdelivr.fyi</code></td>
</tr>
<tr>
<td></td>
<td><code>https://dockercf.jsdelivr.fyi</code></td>
</tr>
<tr>
<td></td>
<td><code>https://dockertest.jsdelivr.fyi</code></td>
</tr>
<tr>
<td><a href="https://dockerpull.com/">docker proxy</a></td>
<td><code>https://dockerpull.com</code></td>
</tr>
<tr>
<td><a href="https://dockerproxy.cn/">docker proxy</a></td>
<td><code>https://dockerproxy.cn</code></td>
</tr>
<tr>
<td><a href="https://hub.uuuadc.top/">Docker镜像加速站</a></td>
<td><code>https://hub.uuuadc.top</code></td>
</tr>
<tr>
<td></td>
<td><code>https://docker.1panel.live</code></td>
</tr>
<tr>
<td></td>
<td><code>https://hub.rat.dev</code></td>
</tr>
<tr>
<td><a href="https://docker.anyhub.us.kg/">DockerHub 镜像加速代理</a></td>
<td><code>https://docker.anyhub.us.kg</code></td>
</tr>
<tr>
<td></td>
<td><code>https://docker.chenby.cn</code></td>
</tr>
<tr>
<td></td>
<td><code>https://dockerhub.jobcher.com</code></td>
</tr>
<tr>
<td><a href="https://dockerhub.icu/">镜像使用说明</a></td>
<td><code>https://dockerhub.icu</code></td>
</tr>
<tr>
<td><a href="https://docker.ckyl.me/">Docker镜像加速站</a></td>
<td><code>https://docker.ckyl.me</code></td>
</tr>
<tr>
<td><a href="https://docker.awsl9527.cn/">镜像使用说明</a></td>
<td><code>https://docker.awsl9527.cn</code></td>
</tr>
<tr>
<td><a href="https://docker.hpcloud.cloud/">镜像使用说明</a></td>
<td><code>https://docker.hpcloud.cloud</code></td>
</tr>
<tr>
<td><a href="https://github.com/DaoCloud/public-image-mirror">DaoCloud 镜像站</a></td>
<td><code>https://docker.m.daocloud.io</code></td>
</tr>
<tr>
<td><a href="https://atomhub.openatom.cn/">AtomHub 可信镜像仓库平台</a> (只包含基础镜像,共336个)</td>
<td><code>https://atomhub.openatom.cn</code></td>
</tr>
</tbody>
</table>
<h1 id="附件代码">附件代码</h1>
<pre><code class="language-javascript">// _worker.js
// Docker镜像仓库主机地址
let hub_host = 'registry-1.docker.io'
// Docker认证服务器地址
const auth_url = 'https://auth.docker.io'
// 自定义的工作服务器地址
let workers_url = 'https://你的域名'
// 根据主机名选择对应的上游地址
function routeByHosts(host) {
// 定义路由表
const routes = {
// 生产环境
"quay": "quay.io",
"gcr": "gcr.io",
"k8s-gcr": "k8s.gcr.io",
"k8s": "registry.k8s.io",
"ghcr": "ghcr.io",
"cloudsmith": "docker.cloudsmith.io",
// 测试环境
"test": "registry-1.docker.io",
};
if (host in routes) return [ routes[host], false ];
else return [ hub_host, true ];
}
/** @type {RequestInit} */
const PREFLIGHT_INIT = {
// 预检请求配置
headers: new Headers({
'access-control-allow-origin': '*', // 允许所有来源
'access-control-allow-methods': 'GET,POST,PUT,PATCH,TRACE,DELETE,HEAD,OPTIONS', // 允许的HTTP方法
'access-control-max-age': '1728000', // 预检请求的缓存时间
}),
}
/**
* 构造响应
* @param {any} body 响应体
* @param {number} status 响应状态码
* @param {Object<string, string>} headers 响应头
*/
function makeRes(body, status = 200, headers = {}) {
headers['access-control-allow-origin'] = '*' // 允许所有来源
return new Response(body, { status, headers }) // 返回新构造的响应
}
/**
* 构造新的URL对象
* @param {string} urlStr URL字符串
*/
function newUrl(urlStr) {
try {
return new URL(urlStr) // 尝试构造新的URL对象
} catch (err) {
return null // 构造失败返回null
}
}
function isUUID(uuid) {
// 定义一个正则表达式来匹配 UUID 格式
const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[4][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
// 使用正则表达式测试 UUID 字符串
return uuidRegex.test(uuid);
}
async function nginx() {
const text = `
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
`
return text ;
}
export default {
async fetch(request, env, ctx) {
const getReqHeader = (key) => request.headers.get(key); // 获取请求头
let url = new URL(request.url); // 解析请求URL
workers_url = `https://${url.hostname}`;
const pathname = url.pathname;
const hostname = url.searchParams.get('hubhost') || url.hostname;
const hostTop = hostname.split('.')[0];// 获取主机名的第一部分
const checkHost = routeByHosts(hostTop);
hub_host = checkHost[0]; // 获取上游地址
const fakePage = checkHost[1];
console.log(`域名头部: ${hostTop}\n反代地址: ${hub_host}\n伪装首页: ${fakePage}`);
const isUuid = isUUID(pathname.split('/')[1].split('/')[0]);
const conditions = [
isUuid,
pathname.includes('/_'),
pathname.includes('/r'),
pathname.includes('/v2/user'),
pathname.includes('/v2/orgs'),
pathname.includes('/v2/_catalog'),
pathname.includes('/v2/categories'),
pathname.includes('/v2/feature-flags'),
pathname.includes('search'),
pathname.includes('source'),
pathname === '/',
pathname === '/favicon.ico',
pathname === '/auth/profile',
];
if (conditions.some(condition => condition) && (fakePage === true || hostTop == 'docker')) {
if (env.URL302){
return Response.redirect(env.URL302, 302);
} else if (env.URL){
if (env.URL.toLowerCase() == 'nginx'){
//首页改成一个nginx伪装页
return new Response(await nginx(), {
headers: {
'Content-Type': 'text/html; charset=UTF-8',
},
});
} else return fetch(new Request(env.URL, request));
}
const newUrl = new URL("https://registry.hub.docker.com" + pathname + url.search);
// 复制原始请求的标头
const headers = new Headers(request.headers);
// 确保 Host 头部被替换为 hub.docker.com
headers.set('Host', 'registry.hub.docker.com');
const newRequest = new Request(newUrl, {
method: request.method,
headers: headers,
body: request.method !== 'GET' && request.method !== 'HEAD' ? await request.blob() : null,
redirect: 'follow'
});
return fetch(newRequest);
}
// 修改包含 %2F 和 %3A 的请求
if (!/%2F/.test(url.search) && /%3A/.test(url.toString())) {
let modifiedUrl = url.toString().replace(/%3A(?=.*?&)/, '%3Alibrary%2F');
url = new URL(modifiedUrl);
console.log(`handle_url: ${url}`)
}
// 处理token请求
if (url.pathname.includes('/token')) {
let token_parameter = {
headers: {
'Host': 'auth.docker.io',
'User-Agent': getReqHeader("User-Agent"),
'Accept': getReqHeader("Accept"),
'Accept-Language': getReqHeader("Accept-Language"),
'Accept-Encoding': getReqHeader("Accept-Encoding"),
'Connection': 'keep-alive',
'Cache-Control': 'max-age=0'
}
};
let token_url = auth_url + url.pathname + url.search
return fetch(new Request(token_url, request), token_parameter)
}
// 修改 /v2/ 请求路径
if (/^\/v2\/[^/]+\/[^/]+\/[^/]+$/.test(url.pathname) && !/^\/v2\/library/.test(url.pathname)) {
url.pathname = url.pathname.replace(/\/v2\//, '/v2/library/');
console.log(`modified_url: ${url.pathname}`)
}
// 更改请求的主机名
url.hostname = hub_host;
// 构造请求参数
let parameter = {
headers: {
'Host': hub_host,
'User-Agent': getReqHeader("User-Agent"),
'Accept': getReqHeader("Accept"),
'Accept-Language': getReqHeader("Accept-Language"),
'Accept-Encoding': getReqHeader("Accept-Encoding"),
'Connection': 'keep-alive',
'Cache-Control': 'max-age=0'
},
cacheTtl: 3600 // 缓存时间
};
// 添加Authorization头
if (request.headers.has("Authorization")) {
parameter.headers.Authorization = getReqHeader("Authorization");
}
// 发起请求并处理响应
let original_response = await fetch(new Request(url, request), parameter)
let original_response_clone = original_response.clone();
let original_text = original_response_clone.body;
let response_headers = original_response.headers;
let new_response_headers = new Headers(response_headers);
let status = original_response.status;
// 修改 Www-Authenticate 头
if (new_response_headers.get("Www-Authenticate")) {
let auth = new_response_headers.get("Www-Authenticate");
let re = new RegExp(auth_url, 'g');
new_response_headers.set("Www-Authenticate", response_headers.get("Www-Authenticate").replace(re, workers_url));
}
// 处理重定向
if (new_response_headers.get("Location")) {
return httpHandler(request, new_response_headers.get("Location"))
}
// 返回修改后的响应
let response = new Response(original_text, {
status,
headers: new_response_headers
})
return response;
}
};
/**
* 处理HTTP请求
* @param {Request} req 请求对象
* @param {string} pathname 请求路径
*/
function httpHandler(req, pathname) {
const reqHdrRaw = req.headers
// 处理预检请求
if (req.method === 'OPTIONS' &&
reqHdrRaw.has('access-control-request-headers')
) {
return new Response(null, PREFLIGHT_INIT)
}
let rawLen = ''
const reqHdrNew = new Headers(reqHdrRaw)
const refer = reqHdrNew.get('referer')
let urlStr = pathname
const urlObj = newUrl(urlStr)
/** @type {RequestInit} */
const reqInit = {
method: req.method,
headers: reqHdrNew,
redirect: 'follow',
body: req.body
}
return proxy(urlObj, reqInit, rawLen)
}
/**
* 代理请求
* @param {URL} urlObj URL对象
* @param {RequestInit} reqInit 请求初始化对象
* @param {string} rawLen 原始长度
*/
async function proxy(urlObj, reqInit, rawLen) {
const res = await fetch(urlObj.href, reqInit)
const resHdrOld = res.headers
const resHdrNew = new Headers(resHdrOld)
// 验证长度
if (rawLen) {
const newLen = resHdrOld.get('content-length') || ''
const badLen = (rawLen !== newLen)
if (badLen) {
return makeRes(res.body, 400, {
'--error': `bad len: ${newLen}, except: ${rawLen}`,
'access-control-expose-headers': '--error',
})
}
}
const status = res.status
resHdrNew.set('access-control-expose-headers', '*')
resHdrNew.set('access-control-allow-origin', '*')
resHdrNew.set('Cache-Control', 'max-age=1500')
// 删除不必要的头
resHdrNew.delete('content-security-policy')
resHdrNew.delete('content-security-policy-report-only')
resHdrNew.delete('clear-site-data')
return new Response(res.body, {
status,
headers: resHdrNew
})
}
</code></pre>
<h1 id="鸣谢">鸣谢</h1>
<p><a href="https://github.com/muzihuaner">muzihuaner</a>、<a href="https://global.v2ex.com/t/1007922">V2ex网友</a>、<a href="https://github.com/ciiiii/cloudflare-docker-proxy">ciiiii</a>、<a href="https://chatgpt.com/">ChatGPT</a>、<a href="https://t.me/bestcfipas/1900">白嫖哥</a>、<a href="https://t.me/zero_free/80">zero_free频道</a>、<a href="https://github.com/cmliu/CF-Workers-docker.io/issues/8">dongyubin</a>、<a href="https://github.com/cmliu/CF-Workers-docker.io/issues/5">kiko923</a></p>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[JavaScript 教程]]></title>
<id>https://0520.eu.org/post/javascript/</id>
<link href="https://0520.eu.org/post/javascript/">
</link>
<updated>2024-05-31T12:21:56.000Z</updated>
<summary type="html"><![CDATA[<p>此教程转载自开源项目 <code>网道(WangDoc.com)</code> <a href="https://github.com/wangdoc/javascript-tutorial">https://github.com/wangdoc/javascript-tutorial</a>,感谢大佬整理分享<br>
<ul class="markdownIt-TOC">
<li><a href="#1-%E5%85%A5%E9%97%A8%E7%AF%87">1. 入门篇</a></li>
<li><a href="#2-%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B">2. 数据类型</a></li>
</ul>
</p>
<h1 id="1-入门篇">1. 入门篇</h1>
<ul>
<li><a href="https://0520.eu.org/post/javascript-basic-introduction/">导论</a></li>
<li><a href="https://0520.eu.org/post/javascript-basic-history/">历史</a></li>
<li><a href="https://0520.eu.org/post/javascript-basic-grammar/">基本语法</a></li>
</ul>
<h1 id="2-数据类型">2. 数据类型</h1>
<ul>
<li><a href="https://0520.eu.org/post/javascript-types-general/">概述</a></li>
<li><a href="https://0520.eu.org/post/javascript-types-null-undefined-boolean/">null,undefined 和布尔值</a></li>
<li><a href="https://0520.eu.org/post/javascript-types-number/">数值</a></li>
<li><a href="https://0520.eu.org/post/javascript-types-string/">字符串</a></li>
<li><a href="https://0520.eu.org/post/javascript-types-object/">对象</a></li>
<li><a href="https://0520.eu.org/post/javascript-types-function/">函数</a></li>
<li><a href="https://0520.eu.org/post/javascript-types-array/">数组</a></li>
</ul>
]]></summary>
<content type="html"><![CDATA[<p>此教程转载自开源项目 <code>网道(WangDoc.com)</code> <a href="https://github.com/wangdoc/javascript-tutorial">https://github.com/wangdoc/javascript-tutorial</a>,感谢大佬整理分享<br>
<ul class="markdownIt-TOC">
<li><a href="#1-%E5%85%A5%E9%97%A8%E7%AF%87">1. 入门篇</a></li>
<li><a href="#2-%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B">2. 数据类型</a></li>
<li><a href="#3-%E8%BF%90%E7%AE%97%E7%AC%A6">3. 运算符</a></li>
<li><a href="#4-%E8%AF%AD%E6%B3%95%E4%B8%93%E9%A2%98">4. 语法专题</a></li>
<li><a href="#5-%E6%A0%87%E5%87%86%E5%BA%93">5. 标准库</a></li>
<li><a href="#6-%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1%E7%BC%96%E7%A8%8B">6. 面向对象编程</a></li>
<li><a href="#7-%E5%BC%82%E6%AD%A5%E6%93%8D%E4%BD%9C">7. 异步操作</a></li>
<li><a href="#8-dom">8. DOM</a></li>
<li><a href="#9-%E4%BA%8B%E4%BB%B6">9. 事件</a></li>
<li><a href="#10-%E6%B5%8F%E8%A7%88%E5%99%A8%E6%A8%A1%E5%9E%8B">10. 浏览器模型</a></li>
<li><a href="#11-%E9%99%84%E5%BD%95%E7%BD%91%E9%A1%B5%E5%85%83%E7%B4%A0%E6%8E%A5%E5%8F%A3">11. 附录:网页元素接口</a></li>
</ul>
</p>
<h1 id="1-入门篇">1. 入门篇</h1>
<ul>
<li><a href="https://0520.eu.org/post/javascript-basic-introduction/">导论</a></li>
<li><a href="https://0520.eu.org/post/javascript-basic-history/">历史</a></li>
<li><a href="https://0520.eu.org/post/javascript-basic-grammar/">基本语法</a></li>
</ul>
<h1 id="2-数据类型">2. 数据类型</h1>
<ul>
<li><a href="https://0520.eu.org/post/javascript-types-general/">概述</a></li>
<li><a href="https://0520.eu.org/post/javascript-types-null-undefined-boolean/">null,undefined 和布尔值</a></li>
<li><a href="https://0520.eu.org/post/javascript-types-number/">数值</a></li>
<li><a href="https://0520.eu.org/post/javascript-types-string/">字符串</a></li>
<li><a href="https://0520.eu.org/post/javascript-types-object/">对象</a></li>
<li><a href="https://0520.eu.org/post/javascript-types-function/">函数</a></li>
<li><a href="https://0520.eu.org/post/javascript-types-array/">数组</a></li>
</ul>
<!-- more -->
<h1 id="3-运算符">3. 运算符</h1>
<ul>
<li><a href="https://0520.eu.org/post/javascript-operators-arithmetic/">算术运算符</a></li>
<li><a href="https://0520.eu.org/post/javascript-operators-comparison/">比较运算符</a></li>
<li><a href="https://0520.eu.org/post/javascript-operators-boolean/">布尔运算符</a></li>
<li><a href="https://0520.eu.org/post/javascript-operators-bit/">二进制位运算符</a></li>
<li><a href="https://0520.eu.org/post/javascript-operators-priority/">其他运算符,运算顺序</a></li>
</ul>
<h1 id="4-语法专题">4. 语法专题</h1>
<ul>
<li><a href="https://0520.eu.org/post/javascript-features-conversion/">数据类型的转换</a></li>
<li><a href="https://0520.eu.org/post/javascript-features-error/">错误处理机制</a></li>
<li><a href="https://0520.eu.org/post/javascript-features-style/">编程风格</a></li>
<li><a href="https://0520.eu.org/post/javascript-features-console/">console 对象与控制台</a></li>
</ul>
<h1 id="5-标准库">5. 标准库</h1>
<ul>
<li><a href="https://0520.eu.org/post/javascript-stdlib-object/">Object 对象</a></li>
<li><a href="https://0520.eu.org/post/javascript-stdlib-attributes/">属性描述对象</a></li>
<li><a href="https://0520.eu.org/post/javascript-stdlib-array/">Array 对象</a></li>
<li><a href="https://0520.eu.org/post/javascript-stdlib-wrapper/">包装对象</a></li>
<li><a href="https://0520.eu.org/post/javascript-stdlib-boolean/">Boolean 对象</a></li>
<li><a href="https://0520.eu.org/post/javascript-stdlib-number/">Number 对象</a></li>
<li><a href="https://0520.eu.org/post/javascript-stdlib-string/">String 对象</a></li>
<li><a href="https://0520.eu.org/post/javascript-stdlib-math/">Math 对象</a></li>
<li><a href="https://0520.eu.org/post/javascript-stdlib-date/">Date 对象</a></li>
<li><a href="https://0520.eu.org/post/javascript-stdlib-regexp/">RegExp 对象</a></li>
<li><a href="https://0520.eu.org/post/javascript-stdlib-json/">JSON 对象</a></li>
</ul>
<h1 id="6-面向对象编程">6. 面向对象编程</h1>
<ul>
<li><a href="https://0520.eu.org/post/javascript-oop-new/">实例对象与 new 命令</a></li>
<li><a href="https://0520.eu.org/post/javascript-oop-this/">this 关键字</a></li>
<li><a href="https://0520.eu.org/post/javascript-oop-prototype/">对象的继承</a></li>
<li><a href="https://0520.eu.org/post/javascript-oop-object/">Object 对象的相关方法</a></li>
<li><a href="https://0520.eu.org/post/javascript-oop-strict/">严格模式</a></li>
</ul>
<h1 id="7-异步操作">7. 异步操作</h1>
<ul>
<li><a href="https://0520.eu.org/post/javascript-async-general/">概述</a></li>
<li><a href="https://0520.eu.org/post/javascript-async-timer/">定时器</a></li>
<li><a href="https://0520.eu.org/post/javascript-async-promise/">Promise 对象</a></li>
</ul>
<h1 id="8-dom">8. DOM</h1>
<ul>
<li><a href="https://0520.eu.org/post/javascript-dom-general/">概述</a></li>
<li><a href="https://0520.eu.org/post/javascript-dom-node/">Node 接口</a></li>
<li><a href="https://0520.eu.org/post/javascript-dom-nodelist/">NodeList 接口,HTMLCollection 接口</a></li>
<li><a href="https://0520.eu.org/post/javascript-dom-parentnode/">ParentNode 接口,ChildNode 接口</a></li>
<li><a href="https://0520.eu.org/post/javascript-dom-document/">Document 节点</a></li>
<li><a href="https://0520.eu.org/post/javascript-dom-element/">Element 节点</a></li>
<li><a href="https://0520.eu.org/post/javascript-dom-attributes/">属性的操作</a></li>
<li><a href="https://0520.eu.org/post/javascript-dom-text/">Text 节点和 DocumentFragment 节点</a></li>
<li><a href="https://0520.eu.org/post/javascript-dom-css/">CSS 操作</a></li>
<li><a href="https://0520.eu.org/post/javascript-dom-mutationobserver/">Mutation Observer API</a></li>
</ul>
<h1 id="9-事件">9. 事件</h1>
<ul>
<li><a href="https://0520.eu.org/post/javascript-events-eventtarget/">EventTarget 接口</a></li>
<li><a href="https://0520.eu.org/post/javascript-events-model/">事件模型</a></li>
<li><a href="https://0520.eu.org/post/javascript-events-event/">Event 对象</a></li>
<li><a href="https://0520.eu.org/post/javascript-events-mouse/">鼠标事件</a></li>
<li><a href="https://0520.eu.org/post/javascript-events-keyboard/">键盘事件</a></li>
<li><a href="https://0520.eu.org/post/javascript-events-progress/">进度事件</a></li>
<li><a href="https://0520.eu.org/post/javascript-events-form/">表单事件</a></li>
<li><a href="https://0520.eu.org/post/javascript-events-touch/">触摸事件</a></li>
<li><a href="https://0520.eu.org/post/javascript-events-drag/">拖拉事件</a></li>
<li><a href="https://0520.eu.org/post/javascript-events-common/">其他常见事件</a></li>
<li><a href="https://0520.eu.org/post/javascript-events-globaleventhandlers/">GlobalEventHandlers 接口</a></li>
</ul>
<h1 id="10-浏览器模型">10. 浏览器模型</h1>
<ul>
<li><a href="https://0520.eu.org/post/javascript-bom-engine/">浏览器模型概述</a></li>
<li><a href="https://0520.eu.org/post/javascript-bom-window/">window 对象</a></li>
<li><a href="https://0520.eu.org/post/javascript-bom-navigator/">Navigator 对象,Screen 对象</a></li>
<li><a href="https://0520.eu.org/post/javascript-bom-cookie/">Cookie</a></li>
<li><a href="https://0520.eu.org/post/javascript-bom-xmlhttprequest/">XMLHttpRequest 对象</a></li>
<li><a href="https://0520.eu.org/post/javascript-bom-same-origin/">同源限制</a></li>
<li><a href="https://0520.eu.org/post/javascript-bom-cors/">CORS 通信</a></li>
<li><a href="https://0520.eu.org/post/javascript-bom-storage/">Storage 接口</a></li>
<li><a href="https://0520.eu.org/post/javascript-bom-history/">History 对象</a></li>
<li><a href="https://0520.eu.org/post/javascript-bom-location/">Location 对象,URL 对象,URLSearchParams 对象</a></li>
<li><a href="https://0520.eu.org/post/javascript-bom-arraybuffer/">ArrayBuffer 对象,Blob 对象</a></li>
<li><a href="https://0520.eu.org/post/javascript-bom-file/">File 对象,FileList 对象,FileReader 对象</a></li>
<li><a href="https://0520.eu.org/post/javascript-bom-form/">表单,FormData 对象</a></li>
<li><a href="https://0520.eu.org/post/javascript-bom-indexeddb/">IndexedDB API</a></li>
<li><a href="https://0520.eu.org/post/javascript-bom-webworker/">Web Worker</a></li>
</ul>
<h1 id="11-附录网页元素接口">11. 附录:网页元素接口</h1>
<ul>
<li><a href="https://0520.eu.org/post/javascript-elements-a/"><code><a></code>元素</a></li>
<li><a href="https://0520.eu.org/post/javascript-elements-image/"><code><img></code>元素</a></li>
<li><a href="https://0520.eu.org/post/javascript-elements-form/"><code><form></code>元素</a></li>
<li><a href="https://0520.eu.org/post/javascript-elements-input/"><code><input></code>元素</a></li>
<li><a href="https://0520.eu.org/post/javascript-elements-button/"><code><button></code>元素</a></li>
<li><a href="https://0520.eu.org/post/javascript-elements-option/"><code><option></code>元素</a></li>
<li><a href="https://0520.eu.org/post/javascript-elements-video/"><code><video>,<audio></code>元素</a></li>
</ul>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[JavaScript 教程-附录:网页元素接口-<video>,<audio>元素]]></title>
<id>https://0520.eu.org/post/javascript-elements-video/</id>
<link href="https://0520.eu.org/post/javascript-elements-video/">
</link>
<updated>2024-05-31T12:19:03.000Z</updated>
<summary type="html"><![CDATA[<p><ul class="markdownIt-TOC">
<li><a href="#videoaudio"><code><video>,<audio></code></a>
<ul>
<li><a href="#%E6%A6%82%E8%BF%B0">概述</a></li>
</ul>
</li>
</ul>
</p>
<h1 id="videoaudio"><code><video>,<audio></code></h1>
<h2 id="概述">概述</h2>
<p><code><video></code>元素用来加载视频,是<code>HTMLVideoElement</code>对象的实例。<code><audio></code>元素用来加载音频,是<code>HTMLAudioElement</code>对象的实例。而<code>HTMLVideoElement</code>和<code>HTMLAudioElement</code>都继承了<code>HTMLMediaElement</code>,所以这两个 HTML 元素有许多共同的属性和方法,可以放在一起介绍。</p>
<p>理论上,这两个 HTML 元素直接用<code>src</code>属性指定媒体文件,就可以使用了。</p>
]]></summary>
<content type="html"><![CDATA[<p><ul class="markdownIt-TOC">
<li><a href="#videoaudio"><code><video>,<audio></code></a>
<ul>
<li><a href="#%E6%A6%82%E8%BF%B0">概述</a></li>
<li><a href="#htmlmediaelement-%E6%8E%A5%E5%8F%A3">HTMLMediaElement 接口</a></li>
<li><a href="#htmlvideoelement-%E6%8E%A5%E5%8F%A3">HTMLVideoElement 接口</a></li>
<li><a href="#htmlaudioelement-%E6%8E%A5%E5%8F%A3">HTMLAudioElement 接口</a></li>
<li><a href="#%E4%BA%8B%E4%BB%B6">事件</a></li>
</ul>
</li>
</ul>
</p>
<h1 id="videoaudio"><code><video>,<audio></code></h1>
<h2 id="概述">概述</h2>
<p><code><video></code>元素用来加载视频,是<code>HTMLVideoElement</code>对象的实例。<code><audio></code>元素用来加载音频,是<code>HTMLAudioElement</code>对象的实例。而<code>HTMLVideoElement</code>和<code>HTMLAudioElement</code>都继承了<code>HTMLMediaElement</code>,所以这两个 HTML 元素有许多共同的属性和方法,可以放在一起介绍。</p>
<p>理论上,这两个 HTML 元素直接用<code>src</code>属性指定媒体文件,就可以使用了。</p>
<!-- more -->
<pre><code class="language-html"><audio src="background_music.mp3"/>
<video src="news.mov" width=320 height=240/>
</code></pre>
<p>注意,<code><video></code>元素有<code>width</code>属性和<code>height</code>属性,可以指定宽和高。<code><audio></code>元素没有这两个属性,因为它的播放器外形是浏览器给定的,不能指定。</p>
<p>实际上,不同的浏览器支持不同的媒体格式,我们不得不用<code><source></code>元素指定同一个媒体文件的不同格式。</p>
<pre><code class="language-html"><audio id="music">
<source src="music.mp3" type="audio/mpeg">
<source src="music.ogg" type='audio/ogg; codec="vorbis"'>
</audio>
</code></pre>
<p>浏览器遇到支持的格式,就会忽略后面的格式。</p>
<p>这两个元素都有一个<code>controls</code>属性,只有打开这个属性,才会显示控制条。注意,<code><audio></code>元素如果不打开<code>controls</code>属性,根本不会显示,而是直接在背景播放。</p>
<h2 id="htmlmediaelement-接口">HTMLMediaElement 接口</h2>
<p><code>HTMLMediaElement</code>并没有对应的 HTML 元素,而是作为<code><video></code>和<code><audio></code>的基类,定义一些它们共同的属性和方法。</p>
<p><code>HTMLMediaElement</code>接口有以下属性。</p>
<ul>
<li>HTMLMediaElement.audioTracks:返回一个类似数组的对象,表示媒体文件包含的音轨。</li>
<li>HTMLMediaElement.autoplay:布尔值,表示媒体文件是否自动播放,对应 HTML 属性<code>autoplay</code>。</li>
<li>HTMLMediaElement.buffered:返回一个 TimeRanges 对象,表示浏览器缓冲的内容。该对象的<code>length</code>属性返回缓存里面有多少段内容,<code>start(rangeId)</code>方法返回指定的某段内容(从0开始)开始的时间点,<code>end()</code>返回指定的某段内容结束的时间点。该属性只读。</li>
<li>HTMLMediaElement.controls:布尔值,表示是否显示媒体文件的控制栏,对应 HTML 属性<code>controls</code>。</li>
<li>HTMLMediaElement.controlsList:返回一个类似数组的对象,表示是否显示控制栏的某些控件。该对象包含三个可能的值:<code>nodownload</code>、<code>nofullscreen</code>和<code>noremoteplayback</code>。该属性只读。</li>
<li>HTMLMediaElement.crossOrigin:字符串,表示跨域请求时是否附带用户信息(比如 Cookie),对应 HTML 属性<code>crossorigin</code>。该属性只有两个可能的值:<code>anonymous</code>和<code>use-credentials</code>。</li>
<li>HTMLMediaElement.currentSrc:字符串,表示当前正在播放的媒体文件的绝对路径。该属性只读。</li>
<li>HTMLMediaElement.currentTime:浮点数,表示当前播放的时间点。</li>
<li>HTMLMediaElement.defaultMuted:布尔值,表示默认是否关闭音量,对应 HTML 属性<code>muted</code>。</li>
<li>HTMLMediaElement.defaultPlaybackRate:浮点数,表示默认的播放速率,默认是1.0。</li>
<li>HTMLMediaElement.disableRemotePlayback:布尔值,是否允许远程回放,即远程回放的时候是否会有工具栏。</li>
<li>HTMLMediaElement.duration:浮点数,表示媒体文件的时间长度(单位秒)。如果当前没有媒体文件,该属性返回0。该属性只读。</li>
<li>HTMLMediaElement.ended:布尔值,表示当前媒体文件是否已经播放结束。该属性只读。</li>
<li>HTMLMediaElement.error:返回最近一次报错的错误对象,如果没有报错,返回<code>null</code>。</li>
<li>HTMLMediaElement.loop:布尔值,表示媒体文件是否会循环播放,对应 HTML 属性<code>loop</code>。</li>
<li>HTMLMediaElement.muted:布尔值,表示音量是否关闭。</li>
<li>HTMLMediaElement.networkState:当前网络状态,共有四个可能的值。0表示没有数据;1表示媒体元素处在激活状态,但是还没开始下载;2表示下载中;3表示没有找到媒体文件。</li>
<li>HTMLMediaElement.paused:布尔值,表示媒体文件是否处在暂停状态。该属性只读。</li>
<li>HTMLMediaElement.playbackRate:浮点数,表示媒体文件的播放速度,1.0是正常速度。如果是负数,表示向后播放。</li>
<li>HTMLMediaElement.played:返回一个 TimeRanges 对象,表示播放的媒体内容。该属性只读。</li>
<li>HTMLMediaElement.preload:字符串,表示应该预加载哪些内容,可能的值为<code>none</code>、<code>metadata</code>和<code>auto</code>。</li>
<li>HTMLMediaElement.readyState:整数,表示媒体文件的准备状态,可能的值为0(没有任何数据)、1(已获取元数据)、2(可播放当前帧,但不足以播放多个帧)、3(可以播放多帧,至少为两帧)、4(可以流畅播放)。该属性只读。</li>
<li>HTMLMediaElement.seekable:返回一个 TimeRanges 对象,表示一个用户可以搜索的媒体内容范围。该属性只读。</li>
<li>HTMLMediaElement.seeking:布尔值,表示媒体文件是否正在寻找新位置。该属性只读。</li>
<li>HTMLMediaElement.src:字符串,表示媒体文件所在的 URL,对应 HTML 属性<code>src</code>。</li>
<li>HTMLMediaElement.srcObject:返回<code>src</code>属性对应的媒体文件资源,可能是<code>MediaStream</code>、<code>MediaSource</code>、<code>Blob</code>或<code>File</code>对象。直接指定这个属性,就可以播放媒体文件。</li>
<li>HTMLMediaElement.textTracks:返回一个类似数组的对象,包含所有文本轨道。该属性只读。</li>
<li>HTMLMediaElement.videoTracks:返回一个类似数组的对象,包含多有视频轨道。该属性只读。</li>
<li>HTMLMediaElement.volume:浮点数,表示音量。0.0 表示静音,1.0 表示最大音量。</li>
</ul>
<p><code>HTMLMediaElement</code>接口有如下方法。</p>
<ul>
<li>HTMLMediaElement.addTextTrack():添加文本轨道(比如字幕)到媒体文件。</li>
<li>HTMLMediaElement.captureStream():返回一个 MediaStream 对象,用来捕获当前媒体文件的流内容。</li>
<li>HTMLMediaElement.canPlayType():该方法接受一个 MIME 字符串作为参数,用来判断这种类型的媒体文件是否可以播放。该方法返回一个字符串,有三种可能的值,<code>probably</code>表示似乎可播放,<code>maybe</code>表示无法在不播放的情况下判断是否可播放,空字符串表示无法播放。</li>
<li>HTMLMediaElement.fastSeek():该方法接受一个浮点数作为参数,表示指定的时间(单位秒)。该方法将媒体文件移动到指定时间。</li>
<li>HTMLMediaElement.load():重新加载媒体文件。</li>
<li>HTMLMediaElement.pause():暂停播放。该方法没有返回值。</li>
<li>HTMLMediaElement.play():开始播放。该方法返回一个 Promise 对象。</li>
</ul>
<p>下面是<code>play()</code>方法的一个例子。</p>
<pre><code class="language-javascript">var myVideo = document.getElementById('myVideoElement');
myVideo
.play()
.then(() => {
console.log('playing');
})
.catch((error) => {
console.log(error);
});
</code></pre>
<h2 id="htmlvideoelement-接口">HTMLVideoElement 接口</h2>
<p><code>HTMLVideoElement</code>接口代表了<code><video></code>元素。这个接口继承了<code>HTMLMediaElement</code>接口,并且有一些自己的属性和方法。</p>
<p>HTMLVideoElement 接口的属性。</p>
<ul>
<li>HTMLVideoElement.height:字符串,表示视频播放区域的高度(单位像素),对应 HTML 属性<code>height</code>。</li>
<li>HTMLVideoElement.width:字符串,表示视频播放区域的宽度(单位像素),对应 HTML 属性<code>width</code>。</li>
<li>HTMLVideoElement.videoHeight:该属性只读,返回一个整数,表示视频文件自身的高度(单位像素)。</li>
<li>HTMLVideoElement.videoWidth:该属性只读,返回一个整数,表示视频文件自身的宽度(单位像素)。</li>
<li>HTMLVideoElement.poster:字符串,表示一个图像文件的 URL,用来在无法获取视频文件时替代显示,对应 HTML 属性<code>poster</code>。</li>
</ul>
<p>HTMLVideoElement 接口的方法。</p>
<ul>
<li>HTMLVideoElement.getVideoPlaybackQuality():返回一个对象,包含了当前视频回放的一些数据。</li>
</ul>
<h2 id="htmlaudioelement-接口">HTMLAudioElement 接口</h2>
<p><code>HTMLAudioElement</code>接口代表了<code><audio></code>元素。</p>
<p>该接口继承了<code>HTMLMediaElement</code>,但是没有定义自己的属性和方法。浏览器原生提供一个<code>Audio()</code>构造函数,返回的就是<code>HTMLAudioElement</code>实例。</p>
<pre><code class="language-javascript">var song = new Audio([URLString]);
</code></pre>
<p><code>Audio()</code>构造函数接受一个字符串作为参数,表示媒体文件的 URL。如果省略这个参数,可以稍后通过<code>src</code>属性指定。</p>
<p>生成<code>HTMLAudioElement</code>实例以后,不用插入 DOM,可以直接用<code>play()</code>方法在背景播放。</p>
<pre><code class="language-javascript">var a = new Audio();
if (a.canPlayType('audio/wav')) {
a.src = 'soundeffect.wav';
a.play();
}
</code></pre>
<h2 id="事件">事件</h2>
<p><code><video></code>和<code><audio></code>元素有以下事件。</p>
<ul>
<li>loadstart:开始加载媒体文件时触发。</li>
<li>progress:媒体文件加载过程中触发,大概是每秒触发2到8次。</li>
<li>loadedmetadata:媒体文件元数据加载成功时触发。</li>
<li>loadeddata:当前播放位置加载成功后触发。</li>
<li>canplay:已经加载了足够的数据,可以开始播放时触发,后面可能还会请求数据。</li>
<li>canplaythrough:已经加载了足够的数据,可以一直播放时触发,后面不需要继续请求数据。</li>
<li>suspend:已经缓冲了足够的数据,暂时停止下载时触发。</li>
<li>stalled:尝试加载数据,但是没有数据返回时触发。</li>
<li>play:调用<code>play()</code>方法时或自动播放启动时触发。如果已经加载了足够的数据,这个事件后面会紧跟<code>playing</code>事件,否则会触发<code>waiting</code>事件。</li>
<li>waiting:由于没有足够的缓存数据,无法播放或播放停止时触发。一旦缓冲数据足够开始播放,后面就会紧跟<code>playing</code>事件。</li>
<li>playing:媒体开始播放时触发。</li>
<li>timeupdate:<code>currentTime</code>属性变化时触发,每秒可能触发4到60次。</li>
<li>pause:调用<code>pause()</code>方法、播放暂停时触发。</li>
<li>seeking:脚本或者用户要求播放某个没有缓冲的位置,播放停止开始加载数据时触发。此时,<code>seeking</code>属性返回<code>true</code>。</li>
<li>seeked:<code>seeking</code>属性变回<code>false</code>时触发。</li>
<li>ended:媒体文件播放完毕时触发。</li>
<li>durationchange:<code>duration</code>属性变化时触发。</li>
<li>volumechange:音量变化时触发。</li>
<li>ratechange:播放速度或默认的播放速度变化时触发。</li>
<li>abort:停止加载媒体文件时触发,通常是用户主动要求停止下载。</li>
<li>error:网络或其他原因导致媒体文件无法加载时触发。</li>
<li>emptied:由于<code>error</code>或<code>abort</code>事件导致<code>networkState</code>属性变成无法获取数据时触发。</li>
</ul>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[JavaScript 教程-附录:网页元素接口-<option> 元素]]></title>
<id>https://0520.eu.org/post/javascript-elements-option/</id>
<link href="https://0520.eu.org/post/javascript-elements-option/">
</link>
<updated>2024-05-31T12:14:18.000Z</updated>
<summary type="html"><![CDATA[<p><ul class="markdownIt-TOC">