章原創(chuàng)于公眾號:程序猿周先森。本平臺(tái)不定時(shí)更新,喜歡我的文章,歡迎關(guān)注我的微信公眾號。
上一篇文章對Nginx的Location配置進(jìn)行了講解,本篇主要對于Nginx中的Rewrite跳轉(zhuǎn)進(jìn)行講解。因?yàn)槟壳昂芏喙ぷ髑岸碎_發(fā)都會(huì)選擇使用Nginx作為反向代理服務(wù)器,但是平時(shí)業(yè)務(wù)需要難免碰到重寫URL,Nginx的Rewrite跳轉(zhuǎn)有什么使用場景呢?
不得不說的是Apache服務(wù)器規(guī)則庫很強(qiáng)大,做跳轉(zhuǎn)也很簡單,但是Nginx使用Rewrite實(shí)現(xiàn)跳轉(zhuǎn)效率更高,所以這也是我們需要學(xué)習(xí)Nginx的Rewrite模塊的目的所在。Rewrite是Nginx的靜態(tài)重寫模塊,跳轉(zhuǎn)的使用場景有以下幾種情形:
Rewrite如何實(shí)現(xiàn)跳轉(zhuǎn)?
Nginx利用ngxhttprewrite_module模塊解析和處理rewrite請求。Rewrite用于實(shí)現(xiàn)URL重寫,其實(shí)有點(diǎn)類似于重定向功能,可以將用戶的請求重寫至別的目錄,在一定程度上提高了網(wǎng)站安全性。Rewrite支持if條件判斷,但不支持else判斷。而且Rewrite需要PCRE支持,一次重定向最多可以跳轉(zhuǎn)10次,超過10次將返回500錯(cuò)誤。Rewrite模塊包含set命令,可以創(chuàng)建變量用來記錄條件標(biāo)識(shí)或者傳遞變量到其他的Location中。Rewrite實(shí)際上就是使用Nginx已有的全局變量或者通過set命令設(shè)置的變量結(jié)合正則表達(dá)式實(shí)現(xiàn)URL重寫。
Rewrite使用場景
在Nginx中使用Rewrite實(shí)現(xiàn)跳轉(zhuǎn)有以下三種場景:
所以說rewrite語句只允許放在server{ },if{ },location{ }中。接下來我們先看看if指令。
if指令
if指令用于條件匹配判斷,根據(jù)判斷結(jié)果選擇不同的Nginx配置,在server或location中配置。Nginx中的if指令只支持單重判斷,不支持多重判斷。我們簡單看個(gè)例子:
location /test{ index index.html; if ( $scheme=http ){ rewrite / https://www.niyueling.cn permanent; } if ($scheme=https ){ echo "if ---> $scheme"; } }
location上篇文章講過了,這里不再細(xì)講,接下來我們看下rewrite語法.
rewrite語法
rewrite regex replacement [flag]
rewrite將用戶請求的URL基于正則表達(dá)式regex進(jìn)行檢查,匹配到時(shí)將其替換為正則表達(dá)式對應(yīng)的新的URL。若在同一級配置模塊中存在多個(gè)rewrite規(guī)則,則會(huì)自頂向下檢查。replacement則為跳轉(zhuǎn)后的內(nèi)容。[flag]作為標(biāo)識(shí)符用于控制循環(huán)機(jī)制,如果替換后的URL是以http或者h(yuǎn)ttps開頭,則會(huì)直接301永久重定向。
flag參數(shù)介紹
rewrite語句有四種flag狀態(tài):redirect、permanent、break、last。前兩種屬于客戶瀏覽器重新發(fā)起對新地址的請求,后兩種是在WEB服務(wù)器內(nèi)部實(shí)現(xiàn)跳轉(zhuǎn)。
rewrite語法講完了我們可以一起來看看如何實(shí)現(xiàn)幾種方式跳轉(zhuǎn):
(1) 在location中將舊域名永久重定向到新域名
location / {
root /data/html;index index.html;rewrite / http://www.niyueling.cn permanent;}
這里有必要提下臨時(shí)重定向與永久重定向的區(qū)別:
臨時(shí)重定向不會(huì)緩存新域名的解析記錄,但是永久重定向會(huì)緩存新域名的解析記錄。
(2) http自動(dòng)跳轉(zhuǎn)https
有時(shí)候公司項(xiàng)目需要,會(huì)要求整個(gè)網(wǎng)站皆使用https,這時(shí)候?yàn)榱擞脩趔w驗(yàn),我們需要在用戶訪問http站點(diǎn)的時(shí)候自動(dòng)跳轉(zhuǎn)到https站點(diǎn)中。
location / {
root /opt/blog;index index.html;
if ( $scheme=http ){rewrite / https://www.niyueling.cn permanent;}}
上面配置其實(shí)就是如果用戶請求協(xié)議為http的時(shí)候使用rewrite跳轉(zhuǎn)到對應(yīng)的https站點(diǎn)。但是if語句不能去掉,否則就會(huì)陷入死循環(huán)。
(3) 如果用戶請求URL不存在跳轉(zhuǎn)首頁
location / { root /opt/blog; index index.html; if ( !-f $request_filename ){ rewrite (.*) http://www.niyueling.cn; } }
(4) 實(shí)現(xiàn)防盜鏈
防盜鏈實(shí)際上是基于前端攜帶的referer實(shí)現(xiàn),referer可以記錄用戶從哪個(gè)界面跳轉(zhuǎn)而來的標(biāo)志信息。Nginx可以通過ungxhttpreferrer_module模塊來檢查請求的referer信息是否有效實(shí)現(xiàn)防盜鏈功能
location ^~ /test { root /opt/blog; index index.html; valid_referers none blocked server_names *.niyueling.cn www.niyueling.* api.online.test/v1/hostlist ~\.google\. ~\.baidu\.; #定義有效的referer if ($invalid_referer) { #假如是使用其他的無效的referer訪問: return 403; #返回狀態(tài)碼403 } }
如果喜歡我的文章,歡迎關(guān)注我的個(gè)人公眾號
很多其它語言一樣,Go也支持goto跳轉(zhuǎn)語句。 在一個(gè)goto跳轉(zhuǎn)語句中,goto關(guān)鍵字后必須跟隨一個(gè)表明跳轉(zhuǎn)到何處的跳轉(zhuǎn)標(biāo)簽。 我們使用LabelName:這樣的形式來聲明一個(gè)名為LabelName的跳轉(zhuǎn)標(biāo)簽,其中LabelName必須為一個(gè)標(biāo)識(shí)符。 一個(gè)不為空標(biāo)識(shí)符的跳轉(zhuǎn)標(biāo)簽聲明后必須被使用至少一次。
一條跳轉(zhuǎn)標(biāo)簽聲明之后必須立即跟隨一條語句。 如果此聲明的跳轉(zhuǎn)標(biāo)簽使用在一條goto語句中,則當(dāng)此條goto語句被執(zhí)行的時(shí)候,執(zhí)行將跳轉(zhuǎn)到此跳轉(zhuǎn)標(biāo)簽聲明后跟隨的語句。
一個(gè)跳轉(zhuǎn)標(biāo)簽必須聲明在一個(gè)函數(shù)體內(nèi),此跳轉(zhuǎn)標(biāo)簽的使用可以在此跳轉(zhuǎn)標(biāo)簽的聲明之后或者之前,但是此跳轉(zhuǎn)標(biāo)簽的使用不能出現(xiàn)在此跳轉(zhuǎn)標(biāo)簽聲明所處的最內(nèi)層代碼塊之外。
下面這個(gè)例子使用跳轉(zhuǎn)標(biāo)簽聲明和goto跳轉(zhuǎn)語句來實(shí)現(xiàn)了一個(gè)循環(huán):
package main
import "fmt"
func main() {
i :=0
Next: // 跳轉(zhuǎn)標(biāo)簽聲明
fmt.Println(i)
i++
if i < 5 {
goto Next // 跳轉(zhuǎn)
}
}
上面剛提到了一個(gè)跳轉(zhuǎn)標(biāo)簽的使用不能出現(xiàn)在此跳轉(zhuǎn)標(biāo)簽聲明所處的最內(nèi)層代碼塊之外,所以下面的代碼片段中的跳轉(zhuǎn)標(biāo)簽使用都是不合法的。
package main
func main() {
goto Label1 // error
{
Label1:
goto Label2 // error
}
{
Label2:
}
}
另外要注意的一點(diǎn)是,如果一個(gè)跳轉(zhuǎn)標(biāo)簽聲明在某個(gè)變量的作用域內(nèi),則此跳轉(zhuǎn)標(biāo)簽的使用不能出現(xiàn)在此變量的聲明之前。 關(guān)于變量的作用域,請閱讀后面的文章代碼塊和作用域
下面這個(gè)程序編譯不通過:
package main
import "fmt"
func main() {
i :=0
Next:
if i >=5 {
// error: goto Exit jumps over declaration of k
goto Exit
}
k :=i + i
fmt.Println(k)
i++
goto Next
Exit: // 此標(biāo)簽聲明在k的作用域內(nèi),但
// 它的使用在k的作用域之外。
}
剛提到的這條規(guī)則可能會(huì)在今后放寬。 目前,有兩種途徑可以對上面的程序略加修改以使之編譯通過。
第一種途徑是縮小變量k的作用域:
func main() {
i :=0
Next:
if i >=5 {
goto Exit
}
// 創(chuàng)建一個(gè)顯式代碼塊以縮小k的作用域。
{
k :=i + i
fmt.Println(k)
}
i++
goto Next
Exit:
}
第二種途徑是放大變量k的作用域:
func main() {
var k int // 將變量k的聲明移到此處。
i :=0
Next:
if i >=5 {
goto Exit
}
k=i + i
fmt.Println(k)
i++
goto Next
Exit:
}
一個(gè)goto語句必須包含一個(gè)跳轉(zhuǎn)標(biāo)簽名。 一個(gè)break或者continue語句也可以包含一個(gè)跳轉(zhuǎn)標(biāo)簽名,但此跳轉(zhuǎn)標(biāo)簽名是可選的。 包含跳轉(zhuǎn)標(biāo)簽名的break語句一般用于跳出外層的嵌套可跳出流程控制代碼塊。 包含跳轉(zhuǎn)標(biāo)簽名的continue語句一般用于提前結(jié)束外層的嵌套循環(huán)流程控制代碼塊的當(dāng)前循環(huán)步。
如果一條break語句中包含一個(gè)跳轉(zhuǎn)標(biāo)簽名,則此跳轉(zhuǎn)標(biāo)簽必須剛好聲明在一個(gè)包含此break語句的可跳出流程控制代碼塊之前。 我們可以把此跳轉(zhuǎn)標(biāo)簽名看作是其后緊跟隨的可跳出流程控制代碼塊的名稱。 此break語句將立即結(jié)束此可跳出流程控制代碼塊的執(zhí)行。
如果一條continue語句中包含一個(gè)跳轉(zhuǎn)標(biāo)簽名,則此跳轉(zhuǎn)標(biāo)簽必須剛好聲明在一個(gè)包含此continue語句的循環(huán)流程控制代碼塊之前。 我們可以把此跳轉(zhuǎn)標(biāo)簽名看作是其后緊跟隨的循環(huán)流程控制代碼塊的名稱。 此continue語句將提前結(jié)束此循環(huán)流程控制代碼塊的當(dāng)前步的執(zhí)行。
下面是一個(gè)使用了包含跳轉(zhuǎn)標(biāo)簽名的break和continue語句的例子。
package main
import "fmt"
func FindSmallestPrimeLargerThan(n int) int {
Outer:
for n++; ; n++{
for i :=2; ; i++ {
switch {
case i * i > n:
break Outer
case n % i==0:
continue Outer
}
}
}
return n
}
func main() {
for i :=90; i < 100; i++ {
n :=FindSmallestPrimeLargerThan(i)
fmt.Print("最小的比", i, "大的素?cái)?shù)為", n)
fmt.Println()
}
}
本文來自博客園,作者:孫龍-程序員,轉(zhuǎn)載請注明原文鏈接:https://www.cnblogs.com/sunlong88/p/17652663.html
讀本文約需要10分鐘,您可以先關(guān)注我們,避免下次無法找到。
JavaScript基礎(chǔ)教程(上)成哥為大家介紹了JavaScript的基礎(chǔ)知識(shí)、數(shù)據(jù)類型及常用方法,本編文章主要介紹JavaScript的的控制語句、函數(shù)編程及異常處理等相關(guān)知識(shí),下面成哥就為大家一一介紹這些內(nèi)容。
(1)if-else語句
如下所示,使用if-else語句根據(jù)不同的三個(gè)年齡條件在頁面上打印不同的輸出
1. <!DOCTYPE html>
2. <html lang="en">
3. <head>
4. <meta charset="UTF-8">
5. <title>JavaScript基礎(chǔ)教程</title>
6. </head>
7. <body>
8. <script type="text/javascript">
9. // 通過if-else語句判斷年齡應(yīng)該去什么教育
10. let age = 10;
11. if (age > 3 && age < 6) {
12. document.write("Age : " + age + "<b>應(yīng)該上學(xué)前教育</b>");
13. } else if (age >= 6 && age < 18) {
14. document.write("Age : " + age + "<b>應(yīng)該上義務(wù)教育</b>");
15. } else {
16. document.write("Age : " + age + "<b>應(yīng)該上高等教育</b>");
17. }
18. </script>
19. </body>
20. </html>
(2)Switch-case-default語句
1. <!DOCTYPE html>
2. <html lang="en">
3. <head>
4. <meta charset="UTF-8">
5. <title>JavaScript基礎(chǔ)教程</title>
6. </head>
7. <body>
8. <script type="text/javascript">
9. // 通過switch-case語句控制輸出,這邊注意每個(gè)case后面要接break不然程序不會(huì)退出會(huì)自動(dòng)執(zhí)行下面語句
10. let age = 35;
11. switch(age){
12. case 10:
13. document.write('未成年');
14. break;
15. case 18:
16. document.write('成年');
17. break;
18. case 35:
19. document.write('淘汰邊緣的程序員');
20. break;
21. default:
22. document.write('不知道什么人');
23. }
24. </script>
25. </body>
26. </html>
(3)For循環(huán)語句
1. <!DOCTYPE html>
2. <html lang="en">
3. <head>
4. <meta charset="UTF-8">
5. <title>JavaScript基礎(chǔ)教程</title>
6. </head>
7. <body>
8. <script type="text/javascript">
9. // 通過for循環(huán)實(shí)現(xiàn)數(shù)字倒序輸出
10. for (var i = 10; i >= 0; i--) {
11. document.write(i + " ");
12. }
13. </script>
14. </body>
15. </html>
(4)While循環(huán)語句
1. <!DOCTYPE html>
2. <html lang="en">
3. <head>
4. <meta charset="UTF-8">
5. <title>JavaScript基礎(chǔ)教程</title>
6. </head>
7. <body>
8. <script type="text/javascript">
9. // 通過while循環(huán)實(shí)現(xiàn)數(shù)字正序輸出
10. x = 0;
11. while (x < 10) {
12. document.write(x + " ");
13. x++;
14. }
15. </script>
16. </body>
17. </html>
(5)do-while循環(huán)語句
do-while與while的區(qū)別是,do-while是先執(zhí)行循環(huán)體再判斷循環(huán)條件,而while是先判斷循環(huán)條件在執(zhí)行循環(huán)體。
1. <!DOCTYPE html>
2. <html lang="en">
3. <head>
4. <meta charset="UTF-8">
5. <title>JavaScript基礎(chǔ)教程</title>
6. </head>
7. <body>
8. <script type="text/javascript">
9. // 通過do while循環(huán)實(shí)現(xiàn)數(shù)字正序輸出
10. x = 0;
11. do {
12. document.write(x + " ");
13. x++;
14. } while (x < 10);
15. </script>
16. </body>
17. </html>
(6)for-in循環(huán)語句
for-in一般用來遍歷數(shù)組或者對象,遍歷數(shù)組時(shí)遍歷的是數(shù)組的索引,遍歷對象時(shí)是對象的key,下面我們來看看for-in語句的示例
1. <!DOCTYPE html>
2. <html lang="en">
3. <head>
4. <meta charset="UTF-8">
5. <title>JavaScript基礎(chǔ)教程</title>
6. </head>
7. <body>
8. <script type="text/javascript">
9. // 遍歷數(shù)組
10. let arr = [10, 12, 31];
11. for (let a in arr){
12. document.write(arr[a] + " ");
13. }
14. document.write("<br>");
15.
16. // 遍歷對象
17. let obj = {a: 1, b: 2, c: 3};
18. for (let key in obj){
19. document.write("key為: ", key, "值為: ", obj[key], "; ");
20. }
21. </script>
22. </body>
23. </html>
(7)Continue與Break語句
continue與break一般都是用在循環(huán)語句中,其中continue表示執(zhí)行到當(dāng)前不往下再執(zhí)行而是從下一個(gè)循環(huán)繼續(xù)執(zhí)行,而break是表示退出當(dāng)前循環(huán),后面的循環(huán)語句都不執(zhí)行了,具體示例如下所示:
1. <!DOCTYPE html>
2. <html lang="en">
3. <head>
4. <meta charset="UTF-8">
5. <title>JavaScript基礎(chǔ)教程</title>
6. </head>
7. <body>
8. <script type="text/javascript">
9. // continue示例這邊輸出除了3都打印輸出
10. for (let i=5; i>=0; i--){
11. if (i===3){
12. continue;
13. }
14. document.write(i + " ");
15. }
16. document.write("<br>");
17.
18. // break示例,這邊當(dāng)循環(huán)到3時(shí)退出,所以3之前數(shù)字(包含3)都不打印
19. for (let i=5; i>=0; i--){
20. if (i===3){
21. break;
22. }
23. document.write(i + " ");
24. }
25. </script>
26. </body>
27. </html>
在實(shí)際開發(fā)過程中程序經(jīng)常會(huì)遇見各種異常,為了解決該問題JavaScript使用try-catch來捕獲異常,其語法結(jié)構(gòu)如下:
1. try {
2. // 這里寫可能出現(xiàn)異常的代碼
3. } catch (err) {
4. // 在這里寫,出現(xiàn)異常后的處理代碼
5. } finally {
6. //無論try中代碼是否有異常拋出(甚至是try代碼塊中有return語句),finally代碼塊中始終會(huì)被執(zhí)行。
7. }
try-catch語句有如下幾點(diǎn)要注意:
1)語句 try 和 catch 是成對出現(xiàn)的,finally可以寫也可以不寫。
2)如果在 try 中出現(xiàn)了錯(cuò)誤,try 里面出現(xiàn)錯(cuò)誤的語句后面的代碼都不再執(zhí)行,直接跳轉(zhuǎn)到 catch 中,catch 處理錯(cuò)誤信息,finally的內(nèi)容則不論有沒有異常都會(huì)執(zhí)行。
3)如果 try 中沒有出現(xiàn)錯(cuò)誤,則不會(huì)執(zhí)行 catch 中的代碼,執(zhí)行完 try 中的代碼后直接執(zhí)行后面的代碼。
JavaScript中的函數(shù)可以簡要分為以下三類:
1)普通函數(shù)
普通函數(shù)的語句格式如下
1. function common(age){
2. return age + 10;
3. }
2)匿名函數(shù)
匿名函數(shù)也就是沒有名稱的函數(shù)一般當(dāng)參數(shù)使用,如在定時(shí)器中調(diào)用,具體語法格式如下
1. function (args){
2. return args + 1;
3. }
4. // 一般用于當(dāng)做參數(shù)使用,例如:設(shè)置定時(shí)器 setInterval(function(){},5000)
3)自執(zhí)行函數(shù)
自執(zhí)行函數(shù)是當(dāng)HTML頁面加載完自動(dòng)執(zhí)行的函數(shù),具體示例如下
1. <!DOCTYPE html>
2. <html lang="en">
3. <head>
4. <meta charset="UTF-8">
5. <title>JavaScript基礎(chǔ)教程</title>
6. </head>
7. <body>
8. <script type="text/javascript">
9. // 自執(zhí)行函數(shù)在HTML加載完自動(dòng)把'成哥的javascript教程'作為變量傳給函數(shù)然后執(zhí)行
10. (function(arg){
11. document.write(arg);
12. })('成哥的javascript教程')
13. </script>
14. </body>
15. </html>
JavaScript主要就是用于HTML頁面的事件處理。如鼠標(biāo)點(diǎn)擊或者點(diǎn)擊鍵盤某個(gè)按鍵觸發(fā)函數(shù)調(diào)用執(zhí)行,如下所示alert一般用于在瀏覽器頁面彈出一個(gè)小窗口并插入內(nèi)容。
1. <!DOCTYPE html>
2. <html lang="en">
3. <head>
4. <meta charset="UTF-8">
5. <title>JavaScript基礎(chǔ)教程</title>
6. </head>
7. <body>
8.
9. <button onclick="alertMessage('alert使用展示')">點(diǎn)擊我</button>
10.
11. <script type="text/javascript">
12. function alertMessage(message){
13. alert(message)
14. }
15. </script>
16. </body>
17. </html>
JavaScript的函數(shù)事件處理還可以綁定其它常用的觸發(fā)事件具體如下所示:
1. <!DOCTYPE html>
2. <html lang="en">
3. <head>
4. <meta charset="UTF-8">
5. <title>JavaScript基礎(chǔ)教程</title>
6. </head>
7. <body>
8. // onmouseover鼠標(biāo)在這標(biāo)簽上時(shí)設(shè)置標(biāo)簽為紅色
9. // onmouseleave鼠標(biāo)離開這標(biāo)簽時(shí)設(shè)置標(biāo)簽為藍(lán)色
10. // onmouseup鼠標(biāo)沒有點(diǎn)擊時(shí)標(biāo)簽文字設(shè)置為'沒有點(diǎn)擊'
11. // onmousedown鼠標(biāo)點(diǎn)擊時(shí)設(shè)置標(biāo)簽為'被點(diǎn)擊'
12. <a href="JavaScript:void(0)"
13. onmouseover="this.style.color='red'"
14. onmouseleave="this.style.color='blue'"
15. onmouseup="this.text='沒有點(diǎn)擊'"
16. onmousedown="this.text='被點(diǎn)擊'">沒有點(diǎn)擊</a><br>
17. </body>
18. </html>
JavaScript還有如下常用的事件,我們這邊就不一一示例了
1. onLoad :當(dāng)頁面加載完畢后觸發(fā),常用于body元素
2. onUnload :當(dāng)頁面關(guān)閉后觸發(fā),常用于body元素
3. onBlur :當(dāng)失去焦點(diǎn)時(shí)觸發(fā),常用于input表單元素
4. onFocus :當(dāng)獲得焦點(diǎn)時(shí)觸發(fā),常用于input表單元素
5. onClick :當(dāng)點(diǎn)擊時(shí)觸發(fā),可以用于任何元素
6. onMouseOver :當(dāng)鼠標(biāo)懸浮時(shí)觸發(fā)
7. onMouseOut :當(dāng)鼠標(biāo)離開時(shí)觸發(fā)
8. onMouseDown :當(dāng)鼠標(biāo)按下時(shí)觸發(fā)
9. onMouseUp :當(dāng)鼠標(biāo)彈起時(shí)觸發(fā)
10. onMouseMove :當(dāng)鼠標(biāo)移動(dòng)時(shí)觸發(fā)
11. onChange :當(dāng)狀態(tài)改變時(shí)觸發(fā),常用于select下拉選框
12. onSelect :當(dāng)文本框中的文本選中時(shí)觸發(fā)
13. onkeypress :當(dāng)鍵盤按下時(shí)觸發(fā)(要快于onkeydown)
14. onkeydown :當(dāng)鍵盤按下時(shí)觸發(fā)(可能捕獲功能鍵,如上下左右)
15. onkeyup :當(dāng)鍵盤彈起時(shí)觸發(fā)
16. onSubmit :當(dāng)表單提交時(shí)觸發(fā),常用于form表單元素
17. onReset :當(dāng)表單重置時(shí)觸發(fā),常用于form表單元素
至此我們《JavaScript基礎(chǔ)教程》就講完了,如有任何問題歡迎在文章后面進(jìn)行留言。最后如果喜歡本篇文章不要忘了點(diǎn)贊、關(guān)注與轉(zhuǎn)發(fā)哦!
-END-
@IT管理局專注計(jì)算機(jī)領(lǐng)域技術(shù)、大學(xué)生活、學(xué)習(xí)方法、求職招聘、職業(yè)規(guī)劃、職場感悟等類型的原創(chuàng)內(nèi)容。期待與你相遇,和你一同成長。
文章推薦:
*請認(rèn)真填寫需求信息,我們會(huì)在24小時(shí)內(nèi)與您取得聯(lián)系。