92国产精品视频_亚洲a级在线观看_国产精品电影观看_国产精品免费观看在线_精品伊人久久97_亚洲人成在线观_尤物九九久久国产精品的特点_成人激情在线播放_成人黄色大片在线免费观看_亚洲成人精品久久久_久久免费视频在线观看_久久精品国产一区_国产一区二区三区18_亚洲欧美中文字幕在线一区_日韩美女中文字幕_日韩视频免费在线

首頁

nginx配置rewrite的用法詳解

seo達人

文章目錄

rewrite在if中的用法

rewrite中break和last的用法

1.break和last在location{}外部時

2.break和last在location{}內部時

3.break和last用法總結

return的用法

rewrite的語法規則

rewrite應用實例

1.域名跳轉(域名重定向)

2.http跳轉https

3.跳轉二級目錄

4.動靜態請求分離

5.防盜鏈配置

6.偽靜態(將靜態頁面重寫為動態)

7.多個if并用

rewrite在if中的用法

格式:if (條件判斷) { 具體的rewrite規則 }



if條件判斷語句由Nginx內置變量、邏輯判斷符號和目標字符串三部分組成。

其中,內置變量是Nginx固定的非自定義的變量,如,$request_method, $request_uri等。

邏輯判斷符號,有=, !=, ~, ~, !~, !~

!表示相反的意思,~為匹配符號,它右側為正則表達式,區分大小寫,而~為不區分大小寫匹配。

目標字符串可以是正則表達式,通常不用加引號,但表達式中有特殊符號時,比如空格、花括號、分號等,需要用單引號引起來。

1

2

3

4

5

示例1:當http請求方法為post時,返回403狀態碼



if ($request_method = POST)

{

    return 403; 

}

1

2

3

4

示例2:通過瀏覽器標識匹配關鍵字,禁止IE瀏覽器訪問



if ($http_user_agent ~
MSIE) 

{

    return 403;

}

1

2

3

4

限制多個瀏覽器:



if ($http_user_agent ~ "MSIE|firefox|Chrome")

{

    return 403;

}

1

2

3

4

示例3:當請求的文件不存在時,進行重定向或return狀態碼等處理操作



if(!-f $request_filename)

{

    rewrite 語句;

}

1

2

3

4

示例4:判斷uri中某個參數的內容



if($request_uri ~
'gid=\d{6,8}/') 

{

    rewrite 語句;

}

1

2

3

4

\d表示數字,{6,8}表示數字出現的次數是6到8次,當uri中gid參數的值包含6-8個數字那么執行rewrite語句



rewrite中break和last的用法

兩個指令用法相同,但含義不同,需要放到rewrite規則的末尾,用來控制重寫后的鏈接是否繼續被nginx配置執行(主要是rewrite、return指令)。



1.break和last在location{}外部時

測試示例:



server{

    listen 80; 

    server_name test.com;

    root /data/wwwroot/test.com;



    rewrite /1.html /2.html;

    rewrite /2.html /3.html;

}

1

2

3

4

5

6

7

8

請求1.html文件時,會被重定向到2.html,然后被重定向到3.html,最后返回的文件為3.html



示例1:在rewrite 指令后面添加break



server{

    listen 80; 

    server_name test.com;

    root /data/wwwroot/test.com;



    rewrite /1.html /2.html break;

    rewrite /2.html /3.html;

}

1

2

3

4

5

6

7

8

請求1.html文件時,會被重定向到2.html,然后直接返回2.html,break在此處的作用就是當匹配第一個rewrite指令成功時,不執行后面的rewrite指令



示例2:當break后面還有location{}的情況



server{

    listen 80; 

    server_name test.com;

    root /data/wwwroot/test.com;



    rewrite /1.html /2.html break;

    rewrite /2.html /3.html;

    location /2.html {

        return 403;

    }

}

1

2

3

4

5

6

7

8

9

10

11

請求1.html文件時,會返回403狀態碼,當1.html被重定向到2.html時,break不會匹配后面的rewrite規則,但條件2.html匹配location{}定義的文件2.html,所以會執行return 403


以上兩個示例中,將break換成last效果一樣



2.break和last在location{}內部時

測試示例:



server{

    listen 80; 

    server_name test.com;

    root /data/wwwroot/test.com;

    

    location / {

        rewrite /1.html /2.html;

        rewrite /2.html /3.html;

    }

    location /2.html

    {

        rewrite /2.html /a.html;

    }

    location /3.html

    {

        rewrite /3.html /b.html;

    }

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

請求1.html,會經過兩次重定向到3.html,3.html又剛好匹配location /3.html{},所以返回b.html,當請求2.html時,會直接返回a.html,因為location /2.html {} 更精準,優先匹配



示例1:在rewrite后面添加break



server{

    listen 80; 

    server_name test.com;

    root /data/wwwroot/test.com;

    

    location / {

        rewrite /1.html /2.html break;

        rewrite /2.html /3.html;

    }

    location /2.html

    {

        rewrite /2.html /a.html;

    }

    location /3.html

    {

        rewrite /3.html /b.html;

    }

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

請求1.html,會返回2.html,不會返回a.html,當break再location {} 內部時,遇到break后,當前location{} 以及后面的location{} 的指令都不再執行



示例2:在rewrite后面添加last



server{

    listen 80; 

    server_name test.com;

    root /data/wwwroot/test.com;

    

    location / {

        rewrite /1.html /2.html last;

        rewrite /2.html /3.html;

    }

    location /2.html

    {

        rewrite /2.html /a.html;

    }

    location /3.html

    {

        rewrite /3.html /b.html;

    }

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

請求1.html時,會返回a.html,在location {} 內部遇到last,當前location {}中剩下的指令不會再執行,但被重定向的url會重新匹配一遍location {}



3.break和last用法總結

1.當rewrite規則在location{}外,break和last作用一樣,遇到break或last后,其后續的rewrite/return語句不再執行。但后續有location{}的話,還會近一步執行location{}里面的語句,前提是請求能匹配該location

2.當rewrite規則在location{}里,遇到break后,本location{}與其他location{}的所有rewrite/return規則都不再執行

3.當rewrite規則在location{}里,遇到last后,本location{}里后續rewrite/return規則不執行,但重寫后的url再次從頭匹配所有location



return的用法

該指令一般用于對請求的客戶端直接返回響應狀態碼。在該作用域內return后面的所有nginx配置都是無效的,可以使用在server、location以及if配置中,除了支持跟狀態碼,還可以跟字符串或者url鏈接。



示例1:直接返回狀態碼



server{

    listen 80;

    server_name www.test.com;

    return 403;

    rewrite www.test.net;  

}

1

2

3

4

5

6

訪問時,直接返回403狀態碼,return返回內容后,后面的配置rewrite不會執行



示例2:當return在if 判斷中時



server {

.....



if ($request_uri ~ ".password|.bak")

{

    return 404;

    rewrite /(.*) /index.html;  

}

.....

}

1

2

3

4

5

6

7

8

9

10

請求的文件包含.password或.bak時,直接返回404,rewrite不會執行,但if {}外的配置會繼續執行,return只在當前作用域中生效



示例3:返回字符串



server{

    listen 80;

    server_name www.test.com;

    return 200 "hello";

}

1

2

3

4

5

返回字符串必須加上狀態碼,否則會報錯



示例4:返回nginx變量



location /1.html {

    return 200 "$host $request_uri";

}

1

2

3

示例5:返回url



server{

    listen 80;

    server_name www.test.com;

    return http://www.test.com/index2.html;

}

1

2

3

4

5

返回url時,必須以http://或https://開頭



示例6:返回html代碼



if ($http_referer ~ 'baidu.com') 

{

    return 200 "<html><script>window.location.href='//$host$request_uri';</script></html>";

}

1

2

3

4

當網站被黑了的時候,從百度點進網站是鏈接都會跳轉到其他網站,可以使用該方法暫時處理

注意:return http://$host$request_uri; 在瀏覽器中會提示"重定向的次數過多"



rewrite的語法規則

格式:rewrite regex replacement [flag]



rewrite 配置可以在server、location以及if配置段內生效



regex 是用于匹配URI的正則表達式,其不會匹配到$host(域名)



replacement 是目標跳轉的URI,可以以http://或者https://開頭,也可以省略掉$host,直接寫$request_uri部分



flag 用來設置rewrite對URI的處理行為,其中有break、last、rediect、permanent,其中break和last在前面已經介紹過,rediect和permanent的區別在于,前者為臨時重定向(302),而后者是永久重定向(301),對于用戶通過瀏覽器訪問,這兩者的效果是一致的。

但是,對于搜索引擎爬蟲來說就有區別了,使用301更有利于SEO。所以,建議replacemnet是以http://或者https://開頭的,flag使用permanent。



示例1:域名跳轉



location / {

    rewrite /(.*) http://www.test.com/$1 permanent;

}

1

2

3

.*為正則表達式,表示uri,用()括起來,在后面的uri中可以調用它,第一次出現的()用$1調用,第二次出現的()用$2調用,以此類推。



示例2:域名跳轉的第二種寫法



location / {

    rewrite /. http://www.test.com$request_uri permanent;

}

1

2

3

示例3:文件跳轉



server{

    listen 80;

    server_name www.test.com;

    root /data/wwwroot/test.com;

    index index.html;

    if ($request_uri !~ '^/web/')

    {

        rewrite /(.
) /web/$1 redirect;

    }

}

1

2

3

4

5

6

7

8

9

10

將uri請求的文件重定向到web/目錄中去尋找



錯誤寫法1:



server{

    listen 80;

    server_name www.test.com;

    root /data/wwwroot/test.com;

    index index.html;

    rewrite /(.*) /web/$1 redirect;

}

1

2

3

4

5

6

7

這樣寫會反復循環,直到瀏覽器最大循環限制次數,哪怕uri包含web/目錄了,也會繼續重定向/web/web/$1



錯誤寫法2:



server{

    listen 80;

    server_name www.test.com;

    root /data/wwwroot/test.com;

    index index.html;

    rewrite /(.*) /web/$1 break;

}

1

2

3

4

5

6

7

添加break后不會導致循環,但如果uri中包含web/目錄的情況下也會被重定向一次,重定向后的uri就是web/web/$1



rewrite應用實例

1.域名跳轉(域名重定向)

單個域名的情況:



server{

    listen 80;

    server_name www.test.com;

    rewrite /(.) http://www.test.net/$1 permanent;    

}

1

2

3

4

5

多個域名的情況:



server{

    listen 80;

    server_name www.test.com www.test.net;

    if ($host != 'www.test.net')

    {

        rewrite /(.
) http://www.test.net/$1 permanent;

    }

}

1

2

3

4

5

6

7

8

2.http跳轉https

server{

    listen 80;

    server_name www.test.com;

    rewrite /(.) https://www.test.com/$1 permanent;

}

1

2

3

4

5

3.跳轉二級目錄

server{

    listen 80;

    server_name bbs.test.com;

    rewrite /(.
) http://www.test.com/bbs/$1 last;

}

1

2

3

4

5

4.動靜態請求分離

server{

    listen 80;

    server_name www.test.com;

    location ~ ..(jpg|jpeg|gif|css|png|js)$

    {

        rewrite /(.*) http://img.test.com/$1 permanent;

    }

}

1

2

3

4

5

6

7

8

假設www.test.com的服務器在國外,訪問速度較慢,img.test.com的服務器在國內,訪問速度正常,可以將訪問www.test.com靜態文件的請求重定向到img.test.com,提高文件返回速度



第二種寫法:



server{

    listen 80;

    server_name www.test.com;

    if ( $uri ~ 'jpg|jpeg|gif|css|png|js$')

    {

        rewrite /(.
) http://img.test.com/$1 permanent;

    }

}

1

2

3

4

5

6

7

8

5.防盜鏈配置

server{

    listen 80;

    server_name www.test.com;

    location ~ ^.+.(jpg|jpeg|gif|css|png|js|rar|zip|flv)$

    {

        valid_referers none blocked server_names
.test.com

        if ($invalid_referer)

        {

            return 403;

        }

    }

}

1

2

3

4

5

6

7

8

9

10

11

12

配置防盜鏈避免別的網站引用www.test.com不想被引用的圖片等文件



http_referer表示從哪兒點擊進網站的,比如從百度搜索引擎訪問的

valid_referers:白名單

invalid_referer:無效的(未在白名單中定義的)

none:允許referer為空(也就是允許直接訪問,未從其他站點跳轉的請求)

blocked:允許來源地址不含http/https



6.偽靜態(將靜態頁面重寫為動態)

location /  {

    rewrite ^([^.])/topic-(.+).html$ $1/portal.php?mod=topic&topic=$2 last;

    rewrite ^([^.]
)/forum-(\w+)-([0-9]+).html$ $1/forum.php?mod=forumdisplay&fid=$2&page=$3 last;

    rewrite ^([^.])/thread-([0-9]+)-([0-9]+)-([0-9]+).html$ $1/forum.php?mod=viewthread&tid=$2&extra=page%3D$4&page=$3 last;

    rewrite ^([^.]
)/group-([0-9]+)-([0-9]+).html$ $1/forum.php?mod=group&fid=$2&page=$3 last;

    rewrite ^([^.])/space-(username|uid)-(.+).html$ $1/home.php?mod=space&$2=$3 last;

    rewrite ^([^.]
)/(fid|tid)-([0-9]+).html$ $1/index.php?action=$2&value=$3 last;

}

1

2

3

4

5

6

7

8

示例為discuz的偽靜態配置



7.多個if并用

location /{

    set $a 0;

    if ($document_uri !~ '^/abc')

    {

        set $a "${a}1"; #uri不以/abc開頭時,$a的值變為01

    }

    if ($http_user_agent ~ 'ie6|firefox')

    {

       set $a "${a}2"; #瀏覽器標識包含ie6或者Firefox時,$a的值變為012

    }

    if ($a = "012") #當滿足前兩個if判斷時,重寫url

    {

        rewrite /(.
) /abc/$1 redirect;

    }

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

nginx配置文件語法不支持if嵌套,需要通過多個if并用判斷時,使用標識變量值的方式處理



藍藍設計m.skdbbs.com )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計  cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務。

使用docbox定制API文檔

seo達人

使用docbox定制API文檔

什么是docbox

docbox的安裝

克隆項目

部署方式

docbox的編寫

定制logo及UI

更換代碼背景色

插入自己的logo

三列改為雙列

其他定制UI



在公司實習了一個月,由于業務需要,我花了大概一周時間對docbox的安裝,編寫,定制化等進行了詳細的研究,下面給大家分享一下我的總結

什么是docbox

Docbox是一個開源的REST API文檔系統。它采用結構化的Markdown文件,并生成帶有導航,固定鏈接的兩列布局。下面是官方example圖片:









docbox的安裝

克隆項目

直接去官網https://github.com/tmcw/docbox,然后克隆即可。



部署方式

在使用npm命令前需要下載Node.js,npm會根據package.json配置文件中的依賴配置下載安裝



接著,在/content下放入.md文件,并使用 npm run build 命令,生成一個包含所需要的js代碼的bundle.js文件,同時創建一個新的index.html文件



重要的就是index.html、bundle.js、/css這三個文件和文件夾



docbox的編寫

在/content下放入.md文件(markdown語法俺就不說了哈……)

對/src/custom/content.js中添加需要引入的.md文件位置和以及標題





注意: /src/custom/content.js中放入的是一級標題、二級和三級標題需要在.md文件中編寫。





定制logo及UI

修改/src/custom/index.js文件

修改對應標簽的屬性即可,定制時修改生成的index.html是沒有用的,因為index.html里的標簽是被動態寫死的。

更換代碼背景色

<div class='round-left pad0y pad1x fill-green code small endpoint-method'>

1





<div class='endpoint dark fill-blue round '>

1





插入自己的logo





修改/src/components/app.js文件



三列改為雙列

docbox默認情況下是顯示三列布局,但我們可以在app.js下進行修改使之默認為雙列布局。將下圖的1改為2即可切換雙列模式







其他定制UI

像下圖一樣,我們可以修改并填寫代碼得到自己想要的頁面樣式,比如說我在最上方加了一個固定位置的區域,然后可以在這個區域添加相應的超鏈接等。







app.js里可以找到圖中對應的標簽和js代碼,docbox支持多種語言切換,我們在需要的地方加入我們想要加入的標簽,并在/css文件夾中對相應的css文件添加樣式就可以定制我們想要的UI啦!??!



下面給大家列出一些用docbox定制API文檔的網站



Mapbox API文檔

Mapillary的API文檔和Tiles文檔

HYCON 8th

Wall

藍藍設計m.skdbbs.com )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計  包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 平面設計服務

一篇解決 thymeleaf 下拉選的選中問題

seo達人

說明:本文基于thymeleaf3.x



在做后臺系統時多多少少都會遇到下拉選回顯的問題,本次就總結一下如何利用thymeleaf簡單快速的進行下拉選的回顯。



兩種情況:

1、下拉選的數據固定死了的情況下?

利用 th:field="${要選中的option的value值}" 屬性,如下

<select id="bookKind" name="bookKind" th:field="${book.bookKind}" class="form-control">

        <option value="">請選擇書的種類</option>

        <option value="1">編程語言</option>

        <option value="2">數據庫</option>

        <option value="3">操作系統</option>

        <option value="4">辦公軟件</option>

        <option value="5">圖形處理與多媒體</option>

</select>

         book是請求域中的實體類,當${book.bookKind}的值和 option 的 value值匹配上后,該option就會被選中。



        怎么樣是不是很簡單?如果是用ajax的話,還要先獲取所有的option,循環遍歷,判斷value值是否相等,設置selected屬性值為true,跳出循環,這一系列操作,thymeleaf一個屬性值就搞定,所以孰輕孰重您就看著來吧!哈哈!



2、下拉選的數據沒固定死時?

兩個屬性  th:each="bookKind : ${bookKinds}" th:selected="{bookKind} == ${book.bookKind}" 搞定,如下所示



<select id="bookKind" name="bookKind" class="form-control">

    <option th:each="bookKind : ${bookKinds}" th:selected="
{bookKind} == ${book.bookKind}" 

            th:value="${bookKind}" th:text="${bookKind}"></option>

</select>

        解釋一下,先th:each遍歷,*{bookKind}代表遍歷出來的元素,判斷與點擊的者一欄的bookKind值是否一樣,如果一樣th:selected的值就為true,然后th:value 設置option的value 值,th:text 設置option的文本值。



試想一下,如果是用ajax會怎么樣?1、先后臺獲取數據后,循環append(html標簽) 2、再獲取到當前記錄的這列屬性值,再獲取到 1 中循環設置的option,在比對value值,設置選中,break等。而且第一個ajax還要整成同步的,不然 2 中可能獲取不到 1 中的option元素。



 



最后說明:如果恰巧能解決你的問題,那就動一動您的小手,點個贊或者評論一下,讓我看到你們,您的點贊或評論將會持續帶給我不懈的動力!!!come on baby!Let's go!

藍藍設計m.skdbbs.com )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計  cs界面設計 、 ipad界面設計  包裝設計 、 圖標定制  用戶體驗 、交互設計、 網站建設 、平面設計服務。

vue-router編程式的導航

seo達人

什么是編程式的導航

除了使用 <router-link> 創建 a 標簽來定義導航鏈接,我們還可以借助 router 的實例方法,通過編寫代碼來實現。



router.push(location, onComplete?, onAbort?)

注意:在 Vue 實例內部,你可以通過 $router 訪問路由實例。因此你可以調用 this.$router.push。



想要導航到不同的 URL,則使用 router.push 方法。這個方法會向 history 棧添加一個新的記錄,所以,當用戶點擊瀏覽器后退按鈕時,則回到之前的 URL。



HTML代碼



<p @click="$router.push('/test/emitView')">跳轉1</p>

<p @click="$router.push({path: '/test/propsView'})">path: '/test/propsView'</p>

<p @click="test">帶參數的跳轉</p>

<p @click="test1">提供了path,params會被忽略</p>

<p @click="$router.push({path: /test/propsView/${userId}})">

    url變為/test/propsView/123

</p>

<p @click="$router.push({path: '/test/propsView', query: {plan: 'private'}})">

    帶參數的url變為/test/propsView?plan=private

</p>

Script中代碼



test () {

    this.$router.push({

        name: 'routerView',

        params: {userId: this.userId, test: 333},

    })

    console.log(this.$route)

    console.log(this.$route.params)

},

test1 () {

    this.$router.push({ // 如果提供了 path,params 會被忽略

        path: 'routerView',

        params: {userId: this.userId, test: 333},

    })

    console.log(this.$route)

    console.log(this.$route.params)

},

router.replace(location, onComplete?, onAbort?)

跟 router.push 很像,唯一的不同就是,它不會向 history 添加新記錄,而是跟它的方法名一樣 —— 替換掉當前的 history 記錄。



router.go(n)

// 在瀏覽器記錄中前進一步,等同于 history.forward()

router.go(1)

 

// 后退一步記錄,等同于 history.back()

router.go(-1)

 

// 如果 history 記錄不夠用,則無反應

router.go(-100)

router.go(100)

router.back()

在瀏覽器記錄中后退一步



router.forward()

在瀏覽器記錄中前進一步


藍藍設計m.skdbbs.com )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計  cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務。

H5之外部瀏覽器喚起微信分享

seo達人

最近在做一個手機站,要求點擊分享可以直接打開微信分享出去。而不是jiathis,share分享這種的點擊出來二維碼。在網上看了很多,都說APP能喚起微信,手機網頁實現不了。也找了很多都不能直接喚起微信。

總結出來一個可以直接喚起微信的。適應手機qq瀏覽器和uc瀏覽器。

下面上代碼,把這些直接放到要轉發的頁面里就可以了:

html部分:


        
  1. <script src="mshare.js"></script>//引進mshare.js
  2. <button data-mshare="0">點擊彈出原生分享面板</button>
  3. <button data-mshare="1">點擊觸發朋友圈分享</button>
  4. <button data-mshare="2">點擊觸發發送給微信朋友</button>

js部分:


        
  1. <script>
  2. var mshare = new mShare({
  3. title: 'Lorem ipsum dolor sit.',
  4. url: 'http://m.ly.com',
  5. desc: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quaerat inventore minima voluptates.',
  6. img: 'http://placehold.it/150x150'
  7. });
  8. $('button').click(function () {
  9. // 1 ==> 朋友圈 2 ==> 朋友 0 ==> 直接彈出原生
  10. mshare.init(+$(this).data('mshare'));
  11. });
  12. </script>

下面是mshare.js的代碼分享,把這些代碼新建一個js文件放進去,然后在頁面中引進就ok了。


        
  1. /**
  2. * 此插件主要作用是在UC和QQ兩個主流瀏覽器
  3. * 上面觸發微信分享到朋友圈或發送給朋友的功能
  4. */
  5. 'use strict';
  6. var UA = navigator.appVersion;
  7. /**
  8. * 是否是 UC 瀏覽器
  9. */
  10. var uc = UA.split('UCBrowser/').length > 1 ? 1 : 0;
  11. /**
  12. * 判斷 qq 瀏覽器
  13. * 然而qq瀏覽器分高低版本
  14. * 2 代表高版本
  15. * 1 代表低版本
  16. */
  17. var qq = UA.split('MQQBrowser/').length > 1 ? 2 : 0;
  18. /**
  19. * 是否是微信
  20. */
  21. var wx = /micromessenger/i.test(UA);
  22. /**
  23. * 瀏覽器版本
  24. */
  25. var qqVs = qq ? parseFloat(UA.split('MQQBrowser/')[1]) : 0;
  26. var ucVs = uc ? parseFloat(UA.split('UCBrowser/')[1]) : 0;
  27. /**
  28. * 獲取操作系統信息 iPhone(1) Android(2)
  29. */
  30. var os = (function () {
  31. var ua = navigator.userAgent;
  32. if (/iphone|ipod/i.test(ua)) {
  33. return 1;
  34. } else if (/android/i.test(ua)) {
  35. return 2;
  36. } else {
  37. return 0;
  38. }
  39. }());
  40. /**
  41. * qq瀏覽器下面 是否加載好了相應的api文件
  42. */
  43. var qqBridgeLoaded = false;
  44. // 進一步細化版本和平臺判斷
  45. if ((qq && qqVs < 5.4 && os == 1) || (qq && qqVs < 5.3 && os == 1)) {
  46. qq = 0;
  47. } else {
  48. if (qq && qqVs < 5.4 && os == 2) {
  49. qq = 1;
  50. } else {
  51. if (uc && ((ucVs < 10.2 && os == 1) || (ucVs < 9.7 && os == 2))) {
  52. uc = 0;
  53. }
  54. }
  55. }
  56. /**
  57. * qq瀏覽器下面 根據不同版本 加載對應的bridge
  58. * @method loadqqApi
  59. * @param {Function} cb 回調函數
  60. */
  61. function loadqqApi(cb) {
  62. // qq == 0
  63. if (!qq) {
  64. return cb && cb();
  65. }
  66. var script = document.createElement('script');
  67. script.src = (+qq === 1) ? '//3gimg.qq.com/html5/js/qb.js' : '//jsapi.qq.com/get?api=app.share';
  68. /**
  69. * 需要等加載過 qq 的 bridge 腳本之后
  70. * 再去初始化分享組件
  71. */
  72. script.onload = function () {
  73. cb && cb();
  74. };
  75. document.body.appendChild(script);
  76. }
  77. /**
  78. * UC瀏覽器分享
  79. * @method ucShare
  80. */
  81. function ucShare(config) {
  82. // ['title', 'content', 'url', 'platform', 'disablePlatform', 'source', 'htmlID']
  83. // 關于platform
  84. // ios: kWeixin || kWeixinFriend;
  85. // android: WechatFriends || WechatTimeline
  86. // uc 分享會直接使用截圖
  87. var platform = '';
  88. var shareInfo = null;
  89. // 指定了分享類型
  90. if (config.type) {
  91. if (os == 2) {
  92. platform = config.type == 1 ? 'WechatTimeline' : 'WechatFriends';
  93. } else if (os == 1) {
  94. platform = config.type == 1 ? 'kWeixinFriend' : 'kWeixin';
  95. }
  96. }
  97. shareInfo = [config.title, config.desc, config.url, platform, '', '', ''];
  98. // android
  99. if (window.ucweb) {
  100. ucweb.startRequest && ucweb.startRequest('shell.page_share', shareInfo);
  101. return;
  102. }
  103. if (window.ucbrowser) {
  104. ucbrowser.web_share && ucbrowser.web_share.apply(null, shareInfo);
  105. return;
  106. }
  107. }
  108. /**
  109. * qq 瀏覽器分享函數
  110. * @method qqShare
  111. */
  112. function qqShare(config) {
  113. var type = config.type;
  114. //微信好友 1, 微信朋友圈 8
  115. type = type ? ((type == 1) ? 8 : 1) : '';
  116. var share = function () {
  117. var shareInfo = {
  118. 'url': config.url,
  119. 'title': config.title,
  120. 'description': config.desc,
  121. 'img_url': config.img,
  122. 'img_title': config.title,
  123. 'to_app': type,
  124. 'cus_txt': ''
  125. };
  126. if (window.browser) {
  127. browser.app && browser.app.share(shareInfo);
  128. } else if (window.qb) {
  129. qb.share && qb.share(shareInfo);
  130. }
  131. };
  132. if (qqBridgeLoaded) {
  133. share();
  134. } else {
  135. loadqqApi(share);
  136. }
  137. }
  138. /**
  139. * 對外暴露的接口函數
  140. * @method mShare
  141. * @param {Object} config 配置對象
  142. */
  143. function mShare(config) {
  144. this.config = config;
  145. this.init = function (type) {
  146. if (typeof type != 'undefined') this.config.type = type;
  147. try {
  148. if (uc) {
  149. ucShare(this.config);
  150. } else if (qq && !wx) {
  151. qqShare(this.config);
  152. }
  153. } catch (e) {}
  154. }
  155. }
  156. // 預加載 qq bridge
  157. loadqqApi(function () {
  158. qqBridgeLoaded = true;
  159. });
  160. if (typeof module === 'object' && module.exports) {
  161. module.exports = mShare;
  162. } else {
  163. window.mShare = mShare;
  164. }

好了,這樣就可以直接喚起微信進行分享啦

藍藍設計m.skdbbs.com )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計  cs界面設計 、 ipad界面設計 、 包裝設計  圖標定制 、 用戶體驗 、交互設計、 網站建設 平面設計服務。

calc的使用

seo達人

       有張頁面是要求要一屏展示,我想到了媒體查詢,也想到了vw和vh。我先用vw和vh來布局,分為上,中,下三部分。每塊計算寬高,vw和vh可以實現響應式布局,所以就用上了。但媒體查詢用上了卻發現在這邊不好用,這時使用上了calc()屬性。因為上一個人引入了video.js并加上id:#myVideo ,這邊也做相應的計算處理。



注意:要有空格



calc()能計算的計算表達式里,在加號(“+”)和減號(“-”)兩邊要留空格,而乘號(“”)和除號(“”)沒有這個要求。 



.video_rel {

        height: calc(100% - 66px);

        width: calc(51.3% - 60px);

 

        #myVideo {

            width: 100%;

            height: 100%;

        }

    }

CSS3引入了一個有用的功能,就是calc()函數。在指定元素高度或寬度時,你可以基于計算設定,而不是簡單的使用固定數值。這種功能在自適應網頁布局設計中格外有用——針對不同尺寸的設備,你需要動態的調整元素的大小,產生適合屏幕大小的不同布局。

 

藍藍設計m.skdbbs.com )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計  cs界面設計 、 ipad界面設計 、 包裝設計  圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務。

六、HTTP協議中的緩存

seo達人

一、緩存簡介

緩存無處不在,瀏覽器端的緩存、服務器端的緩存、代理服務器的緩存、對象緩存、數據庫也有緩存……HTTP中具有緩存功能的是瀏覽器緩存和代理服務器緩存。下面說一下緩存的優點:



1.減少冗余的數據傳輸,節省了傳輸時間



2.減少服務器的負擔,大大提高了網站的性能



3.加快了客戶端加載網頁的速度



二、使用Fiddler如何查看緩存的Header

與緩存相關的內容放在Header中的Cache項里;Requests和Responses均是這樣。如圖:







三、緩存的新鮮度(通過什么方式判斷其是否,如何刷新緩存)

Web服務器通過兩種方式判斷瀏覽器緩存是否:



(1)瀏覽器把緩存文件的最后修改時間通過Header“If-Modified-Since”項傳遞給Web服務器。



(2)瀏覽器把緩存文件的ETag通過Header“If-None-Match”項傳遞給Web服務器。



簡單描述一下,瀏覽器端想請求一個文檔,它首先檢查本地緩存,發現存在這個文檔的緩存,獲取緩存文檔的最后修改時間,發送請求,將值放在Header中的“If-Modified-Since”項傳遞給Web服務器。Web服務器接收到請求后,將服務器的文檔修改時間(Last-Modified)與HTTP請求中的header中的“If-Modified-Since”值相比較,有兩種情況,如下面圖示:



1.緩存有效:







2.緩存無效:







截圖舉例:







上面說的是If-Modified-Since值對比的方式;下面說一下ETa'g;



四、ETag

ETag(Entity Tag):實體標簽;是根據實體內容生成的一段hash字符串(類似MD5之后的結果),可以用來標識資源的狀態(當資源發送變化時,ETag也會跟著改變);ETag是Web服務端產生的,然后通過response響應給瀏覽器。使用ETag,主要解決Last-Modified無法解決的情況:



(1.某些服務器不能得到文件的If-Modified-Since來判斷文件是否更新;



(2.某些文件修改非常頻繁,以小于秒的單元進行修改,而Last-Modified最單元為秒;



(3.有些文件最后修改時間變化了,但是內容并沒有變化,所以我們不希望瀏覽器以為文件已變化了;







五、與緩存相關的header

字段名稱 釋義

Cache-Control:max-age=0 以秒為單位

If-Modified-Since:Fri, 11 Jan 2019 01:55:04 GMT 緩存文件的最后修改時間

If-None-Match:W/"5c37f778-732" 緩存文件的Etag的值

Cache-Control:no-cache 不使用緩存

Pragma:no-cache 不使用緩存

Cache-Control:public 響應被緩存,可以共享與多用戶

Cache-Control:private 響應只能私有緩存,不可共享

Cache-Control:no-store 絕對禁止緩存(機密、敏感文件)

Cache-Control:max-age=60 60秒后緩存過期(相對時間)

Date:Fri, 11 Jan 2019 01:55:04 GMT 當前發送時間

Expires:Fri, 11 Jan 2019 01:55:04 GMT 緩存過期時間設置(絕對時間)

Last-Modified:Fri, 11 Jan 2019 01:55:04 GMT 服務器端文件的最后修改時間

Etag:W/"5c37f778-732" 服務器端文件的Etag值

六、關于緩存的常識

1.如何讓瀏覽器不使用緩存?



答:【Ctrl+F5】快捷鍵強制刷新瀏覽器,讓瀏覽器不使用緩存;此時Fiddler抓包所看到的請求Header中都會帶有Cache-Control:no-cache;







2.如何讓瀏覽器直接使用緩存,不請求服務器進行緩存驗證?



答:第一次訪問與第二次訪問同一個網頁;(注意:第二次訪問時,輸入網址,直接回車)瀏覽器會直接使用有效的緩存,而不會發生HTTP請求去服務器驗證緩存,這種情況稱之為緩存命中;



使用Fiddler抓包,現象:第一次訪問,有70多個Session;第二次訪問,僅40多個請求;



3.瀏覽器均可在設置中設置不使用緩存;



4.公有緩存、私有緩存的區別:一個可以多個不同的客戶端使用,一個只可唯一的客戶端使用;


藍藍設計m.skdbbs.com )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計  包裝設計 、 圖標定制  用戶體驗 、交互設計、 網站建設 、平面設計服務

JS中鉤子函數與回調函數的區別

seo達人

測試代碼

<!DOCTYPE html>

<html lang="en">

<head>

  <meta charset="UTF-8">

  <title>Title</title>

</head>

<body>

    <button id="btn">按鈕</button>

    <script>

        let btn = document.getElementById("btn");

        btn.onclick = () => { // 鉤子函數

            console.log('我是鉤子函數');

        }

 

        btn.addEventListener("click",() =>{ // 回調函數

            console.log('我是回調函數');

        });

        // 這是給btn綁定了一個監聽器,后面那個函數是它的回調函數,

        // 因為消息捕獲的過程我們并不能參與,而在捕獲執行完畢的時候,

        // 回調函數才會執行,我們可以把對消息的處理寫在回調函數里。

    </script>

</body>

</html>

點擊按鈕后代碼輸出如下:







回調函數和鉤子函數的區別根本上是

鉤子函數在捕獲消息的第一時間就執行,而回調函數是捕獲結束時,最后一個被執行的。



什么是鉤子函數

一般認為,鉤子函數就是回調函數的一種,其實還是有差異的,差異地方就是:觸發的時機不同。

鉤子(Hook)概念源于Windows的消息處理機制,通過設置鉤子,應用程序對所有消息事件進行攔截,然后執行鉤子函數。 



什么是回調函數

回調函數其實是調用者將回調函數的指針傳遞給了調用函數,當調用函數執行完畢后,通過函數指針來調用回調函數。



鉤子函數和回調函數都是事件處理函數


藍藍設計m.skdbbs.com )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計  cs界面設計 、 ipad界面設計 、 包裝設計  圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務。

數組常用的方法

seo達人

數組常見方法

數組的方法

一、join() 方法 ----->不會改變原數組

二、concat() 方法 ----->不會改變原數組

三、splice(index, num, item) ----->會改變原數組

  1. splice(index, num) 刪除功能
  2. splice(index, 0, ...item)
  3. splice(index, num, item)
  4. splice(index)

    四、slice() -----> 不會改變原數組

    五、push() 和 pop() ----->會改變原數組

    六、shift() 和 unshift() -----> 會改變原數組

    七、sort() -----> 會改變原數組

    八、reverse() ----->會改變原數組

    九、indexOf() 和 lastIndexOf()

    十、includes()

    十一、forEach()

    十二、map() -----> 不會改變原數組

    十三、filter() -----> 不會改變原數組

    十四、every()

    十五、some()

    十六、reduce() 和 reduceRight()

    十七、Array.from() 將類數組轉化為數組

    十八、Array.of() 方法用于將一組值轉化為數組

    十九、數組實例的 find() 和 findIndex()

    二十、扁平化數組 flat() 方法 -----> 不會改變原數組

    數組的方法

    一、join() 方法 ----->不會改變原數組

    該方法可以將數組里面的元素,通過指定的分隔符以字符串的形式連接起來

    返回值:返回新的字符串



    // join() 將數組轉化為字符串

    let arr = [1, 2, 3, 4, 5]

    let str1 = arr.join('|')

    console.log(arr) // [1, 2, 3, 4, 5]

    console.log(str1) // 1|2|3|4|5

    // 當傳空字符串時

    let str2 = arr.join('') // 12345

    // 當不傳時

    let str3 = arr.join() // 1,2,3,4,5

    1

    2

    3

    4

    5

    6

    7

    8

    9

    二、concat() 方法 ----->不會改變原數組

    該方法可以把兩個數組里的元素拼接成一個新的數組

    返回值:返回拼接后的新數組



    let arr1 = [0, 1, 2]

    let arr2 = [2, 3, 4]

    let arr = arr1.concat(arr2)

    // 傳入二維數組

    let arrCopy = arr1.concat([12, [17, 26]])

    console.log(arrCopy) // [0, 1, 2, 12, [17, 26]]

    console.log(arr) // [0, 1, 2, 2, 3, 4]

    console.log(arr1) // [0, 1, 2]

    console.log(arr2) // [2, 3, 4]



    // ES6 擴展運算符

    let a = [1, 2]

    let b = [2, 3]

    let ab = [...a, ...b] // [1, 2, 2, 3]

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    三、splice(index, num, item) ----->會改變原數組

    index 參數:必傳,整數,規定添加或者刪除的位置,使用負數時,從數組尾部規定位置

    num 參數:必傳,要刪除的數量,如果為 0,則不刪除項目

    item 參數:可選參數,可以是多個,想數組添加的新項目

    splice 具有刪除,插入,替換的功能


  5. splice(index, num) 刪除功能

    index 參數:開始位置的索引



    num 參數:要刪除元素的個數



    返回值:返回的是包含被刪除元素的數組對象



    // 刪除功能

    let array = [1, 2, 3, 4, 5]

    let newArr = array.splice(2, 2)

    console.log(newArr) // [1, 2, 5]

    console.log(array) // [3, 4]



    1

    2

    3

    4

    5

    6
  6. splice(index, 0, …item)

    index 參數:插入元素的索引值

    0 參數:不刪除

    // 插入功能

    let arr = ['a', 'b', 'c', 'd', 'e']

    let newArr = arr.splice(1, 0, ['插入', 1217])

    console.log(newArr) // []

    console.log(arr) // ['a', ['插入', 1217], 'b', 'c', 'd', 'e']



    1

    2

    3

    4

    5

    6
  7. splice(index, num, item)

    index 參數:開始的索引位置

    num 參數:刪除的項個數

    item 參數:替換項

    返回值:返回包含被刪除的元素的數組對象

    let arr = [1, 2, 3, 4, 5]

    let newArr = arr.splice(2, 2, '替換', '1226')

    console.log(newArr) // [3, 4]

    console.log(arr) // [1, 2, '替換', '1226', 5]



    1

    2

    3

    4

    5
  8. splice(index)

    當只傳一個值時,表示從傳入的 index 索引值開始截取到最后

    let arr = [1, 2, 3, 4, 5]

    let newArr = arr.splice(3)

    console.log(newArr) // [4, 5]

    console.log(arr) // [1, 2, 3]

    1

    2

    3

    4

    四、slice() -----> 不會改變原數組

    返回從原數組中指定開始下標到結束下標之間的項組成的新數組

    slice() 方法可以接受一或兩個參數,即要返回項的起始位置和結束位置

    array.slice(2) 若只設置一個參數,起始位置為2(包含下標2)開始到數組最后

    array.slice(2, 5) 若設置兩個參數,起始下標為2(包含下標2)到結束下標5(不包含下標5)的數組

    當 slice() 參數中有負數時,將負數加上數組的長度值來替換該位置的數

    let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9]

    let copyArr1 = arr.slice(2) // [3, 4, 5, 6, 7, 8, 9]

    let copyArr2 = arr.slice(2, 5) // [3, 4, 5] 

    let copyArr3 = arr.slice(-2) // [8, 9]

    let copyArr4 = arr.slice(2, -2) // [3, 4, 5, 6, 7]

    let copyArr5 = arr.slice(-2, -5) // []

    let copyArr6 = arr.slice(-5, -2) // [5, 6, 7]

    console.log(arr) // [1, 2, 3, 4, 5, 6, 7, 8, 9]



    1

    2

    3

    4

    5

    6

    7

    8

    9

    五、push() 和 pop() ----->會改變原數組

    push() 可以接受任意數量的參數,將其逐個添加到數組的末尾,并返回修改后數組的長度(改變了原數組)

    pop() 刪掉數組末尾最后一項,改變了數組的 length 值,并返回刪除的項

    let arr = [1, 2, 3, 4, 5]

    let count = arr.push(0, 1217)

    console.log(count) // 7

    console.loh(arr) // [1, 2, 3, 4, 5, 0, 1217]



    let item = arr.pop()

    console.log(item) // 1217

    console.log(arr) // [1, 2, 3, 4, 5, 0]

    1

    2

    3

    4

    5

    6

    7

    8

    六、shift() 和 unshift() -----> 會改變原數組

    shift() 刪除原數組的第一項,并返回刪除元素的值,如果數組為空折返回 undefined

    unshift() 將參數添加到原數組的開頭,并返回數組的長度

    let arr = [1, 2, 3, 4, 5]

    let item = arr.shift()

    console.log(item) // 1

    console.log(arr) // [2, 3, 4, 5]



    let count = arr.unshift(0, 'Jack')

    console.log(count) // 6

    console.log(arr) // [0, 'Jack', 2, 3, 4, 5]

    1

    2

    3

    4

    5

    6

    7

    8

    七、sort() -----> 會改變原數組

    在排序時,sort() 方法會調用每個數組項的 toString() 轉型方法,然后比較得到的字符串,已確定如何排序,其本質是比較字符串的 ASCII 編碼

    即使數組中的每一項都是數值,sort() 方法比較的也是字符串,因此會出現以下情況:

    let arr1 = ['a', 'd', 'e', 'b', 'c']

    console.log(arr1.sort()) // ['a', 'b', 'c', 'd', 'e']



    let arr2 = [12, 26, 3, 99, 52]

    console.log(arr2.sort()) // [12, 26, 3, 52, 99]



    1

    2

    3

    4

    5

    6

    解決辦法



    let arr3 = [12, 26, 3, 99, 52]

    arr3.sort((a, b) => {

    return a -b

    })

    console.log(arr3) // [3, 12, 26, 52, 99]

    1

    2

    3

    4

    5

    冒泡排序(優化版)



    function mySort (arr) {

    let count = 0 // 記錄循環次數

    // 外層循環  控制循環的次數,每次找到最大值

    for (let i = 0; i < arr.length - 1; i++) {

    count++

    // 判斷是否排序好了

    let isSort = true // 初始值默認已經排序好了

    for (let j = 0; j < arr.length - 1 - i; j++) {

    count++

    if (arr[j] > arr[j + 1]) {

    isSort = false

    // 交換位置

    let tmp = arr[j]

    arr[j] = arr[j + 1]

    arr[j + 1] = tmp

    }

    }

    // 某一趟結束,判斷一下是否結束

    // 如何判斷是否排序好,根據是否發生了位置交換,如果發生了位置交換就說明沒有排序好

    if (isSort) {

    break

    }

    }

    console.log(count)

    return arr

    }

    mySort([12, 26, 17, 520, 99])



    // 打印結果:count 9

    // arr [12, 17, 26, 99, 520]



    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

    八、reverse() ----->會改變原數組

    反轉數組項的順序

    let arr = [1, 2, 3, 4, 5]

    arr.reverse()

    console.log(arr) // [5, 4, 3, 2, 1]



    1

    2

    3

    4

    九、indexOf() 和 lastIndexOf()

    indexOf() 接受兩個參數:要查找的項和查找起點位置的索引(可選項),其中從數組的開頭開始向后查找

    lastIndexOf() 接受兩個參數:要查找的項和查找起點位置的索引(可選項),其中是從數組的末尾開始向前查找

    返回值:當存在時,返回要查找的項在數組中首次出現的索引值;當不存在時,返回 -1

    可以用來判斷一個值是否存在數組中



    let arr = [1, 2, 3, 5, 7, 7, 8, 5, 12, 17]

    console.log(arr.indexOf(5)) // 3

    console.log(arr.lastIndexOf(5)) // 7



    console.log(arr.indexOf(5, 2)) // 3

    console.log(arr.lastIndexOf(5, 4)) // 3



    console.log(arr.indexOf('5')) // -1

    1

    2

    3

    4

    5

    6

    7

    8

    十、includes()

    Array.prototype.includes() 數組實例的方法

    返回一個布爾值,表示某個數組是否包含給定的值

    推薦使用:可以用來判斷一個值是否存在數組中



    let arr = [1, 2, 3, 4, 5]

    console.log(arr.includes(3)) // true

    console.log(arr.includes(0)) // false

    1

    2

    3

    十一、forEach()

    對數組進行遍歷,對數組中的每一項運行給定函數,沒有返回值



    forEarch(function (item, index, array) {})



    參數 item:表示數組中的每一項

    參數 index:表示數組中每一項對應的索引值

    參數 array:表示數組本身

    let arr = [1, 2, 3, 4, 5]

    arr.forEach((item, index, array) => {

    console.log(item + '---' + index + '---' + (arr === array))

    })

    1

    2

    3

    4

    十二、map() -----> 不會改變原數組

    map() 方法是將數組中的每一項調用提供的函數,結果返回一個新數組,并沒有改變原來的數組

    映射



    let arr = [1, 2, 3, 4, 5]

    let newArr = arr.map(item => item * item)



    console.log(newArr) // [1, 4, 9, 16, 25]

    console.log(arr) // [1, 2, 3, 4, 5]

    1

    2

    3

    4

    5

    十三、filter() -----> 不會改變原數組

    filter() 方法是將數組中所有的元素進行判斷,將滿足條件的元素作為一個新數組返回

    過濾



    let arr = [12, 17, 26, 520, 1314]

    let newArr = arr.filter((item, index) => {

    return item > 20

    })

    console.log(newArr) // [26, 520, 1314]

    1

    2

    3

    4

    5

    十四、every()

    every() 判斷數組中每一項都是否滿足條件,只有所有項都滿足條件才返回 true,否則返回 false

    let arr = [1, 2, 3, 4, 5]

    let boolean1 = arr.every(item => item > 0)

    let boolean2 = arr.every(item => item > 3)



    console.log(boolean1) // true

    console.log(boolean2) // false

    1

    2

    3

    4

    5

    6

    十五、some()

    some() 判斷數組中是否存在滿足條件的項,只要有一項滿足條件,就會返回 true,否則返回 false

    let arr = [1, 2, 3, 4, 5]

    let boolean3 = arr.some(item => item > 3)

    let boolean4 = arr.some(item => item < 0)



    console.log(boolean3) // true

    console.log(boolean4) // false

    1

    2

    3

    4

    5

    6

    十六、reduce() 和 reduceRight()

    reduce() 方法是所有元素調用返回函數,返回值為最后結果,傳入的值必須是函數類型

    接受兩個參數:每一項調用的函數和作為歸并基礎的初始值(可選項)

    這個函數返回的任何值都會作為第一個參數自動傳給下一項。第一次迭代發生在數組的第二項上,因此第一個參數是數組的第一項,第二個參數就是數組的第二項。



    // 利用 reduce() 方法實現數組求和,給數組一開始家里一個初始值 3

    let arr = [1, 2, 3, 4, 5]

    let sum = arr.reduce((prev, cur, index, array) => {

    // 函數接受 4 個參數:

    // 前一個值、當前值、項的索引值、原數組對象

    console.log(prev, '---', cur, '---', index, '---', array)

    return prev + cur

    }, 3)

    console.log(sum) // 18 = 15 + 3

    1

    2

    3

    4

    5

    6

    7

    8

    9

    與之相對應的還有一個 Array.reduceRight() 方法,區別是這個是從右向左操作的



    十七、Array.from() 將類數組轉化為數組

    let arrayLike = {

    '0': 'a',

    '1': 'b',

    '2': 'c',

    '3': 'd',

    length: 4

    }

    // ES5 寫法

    let arr1 = [].slice.call(arrayLike) // ['a', 'b', 'c', 'd']



    // ES6

    let arr2 = Array.from(arrayLike) // ['a', 'b', 'c', 'd']

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    十八、Array.of() 方法用于將一組值轉化為數組

    Array.of總是返回參數值組成的數組。如果沒有參數,就返回一個空數組。



    Array.of(1, 2, 3, 4, 5) // [1, 2, 3, 4, 5]

    Array.of('abcd') // ['abcd']

    Array.of('abcd').length // 1

    Array.of() // []



    // Array.of 方法的實現

    function ArrayOf () {

    return [].slice.call(arguments)

    }

    1

    2

    3

    4

    5

    6

    7

    8

    9

    十九、數組實例的 find() 和 findIndex()

    數組實例的 find() 方法,用于找出第一個符合條件的數組成員

    它的參數是一個回調函數,所有數組成員依次執行該回調函數,直到找出第一個返回值為 true 的成員,然后就返回該成員,如果沒有符合條件的成員,則返回 undefined

    let arr = [1, 2, 3, 4, 5]

    let value= arr.find((item, index, array) => {

    // item 表示循環遍歷數組的每一項

    // index 每一項對應的索引值

    // array 原數組對象

    return item > 3

    })

    console.log(value) // 4

    console.log(arr) // [1, 2, 3, 4, 5]



    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    數組實例的 findIndex方法的用法與find方法非常類似,返回第一個符合條件的數組成員的位置,如果所有成員都不符合條件,則返回 -1

    let arr = [1, 2, 3, 4, 5]

    let index = arr.findIndex((item, index, array) => {

    return item > 3

    })



    console.log(index) // 3



    [NaN].indexOf(NaN) // -1

    [NaN].findIndex(value => Object.is(NaN, value)) // 0

    [NaN].includes(NaN) // true

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    由此可見:一般用來判斷數組中是否存在某個值,推薦使用 includes



    二十、扁平化數組 flat() 方法 -----> 不會改變原數組

    let arr = [1, [2, 3, [4, 5, [6]]]]

    let arrFlat = arr.flat(Infinity)

    console.log(arrFlat) // [1, 2, 3, 4, 5, 6]

    console.log(arr) // [1, [2, 3, [4, 5, [6]]]]

    1

    2

    3

    4

    利用遞歸實現數組扁平化



    let arrayFlat = []

    let myFlat = (arr) => {

    for (let i = 0; i < arr.length; i++) {

    let item= arr[i]

    // 判斷 arr[i] 是否是數組

    if (Array.isArray(item)) {

    // 如果是數組,繼續調用函數 myFlat

    myFlat(item)

    } else {

    arrayFlat.push(item)

    }

    }

    return arrayFlat

    }



    藍藍設計m.skdbbs.com )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計  ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務。

徹底解決小程序無法觸發SESSION問題

seo達人

一、首先找到第一次發起網絡請求的地址,將服務器返回set-cookie當全局變量存儲起來

wx.request({
  ......
  success: function(res) {
    console.log(res.header);
    //set-cookie:PHPSESSID=ic4vj84aaavqgb800k82etisu0; path=/; domain=.fengkui.net

    // 登錄成功,獲取第一次的sessionid,存儲起來
    // 注意:Set-Cookie(開發者工具中調試全部小寫)(遠程調試和線上首字母大寫)
    wx.setStorageSync("sessionid", res.header["Set-Cookie"]);
  }
}) 

二、請求時帶上將sessionid放入request的header頭中傳到服務器,服務器端可直接在cookie中獲取

wx.request({
  ......
  header: {
    'content-type': 'application/json', // 默認值
    'cookie': wx.getStorageSync("sessionid")
    //讀取sessionid,當作cookie傳入后臺將PHPSESSID做session_id使用
  },
  success: function(res) {
    console.log(res)
  }
}) 

三、后臺獲取cookie中的PHPSESSID,將PHPSESSID當作session_id使用

<?php
// 判斷$_COOKIE['PHPSESSID']是否存在,存在則作session_id使用
if ($_COOKIE['PHPSESSID']) {
    session_id($_COOKIE['PHPSESSID']);
}

session_start();
echo session_id(); 

日歷

鏈接

個人資料

藍藍設計的小編 http://m.skdbbs.com

存檔

92国产精品视频_亚洲a级在线观看_国产精品电影观看_国产精品免费观看在线_精品伊人久久97_亚洲人成在线观_尤物九九久久国产精品的特点_成人激情在线播放_成人黄色大片在线免费观看_亚洲成人精品久久久_久久免费视频在线观看_久久精品国产一区_国产一区二区三区18_亚洲欧美中文字幕在线一区_日韩美女中文字幕_日韩视频免费在线
久久婷婷久久| www日韩欧美| 久久精品99国产国产精| 亚洲免费小视频| 99精品视频免费观看| 免费国产自久久久久三四区久久| 久久亚洲国产| 久久av免费观看| 国产美女诱惑一区二区| 久久久久成人精品免费播放动漫| 精品黄色免费中文电影在线播放| 日日噜噜噜夜夜爽亚洲精品| 日韩大片欧美大片| 欧美精品videosex牲欧美| 日韩一区国产二区欧美三区| 久久久久国产视频| 亚洲欧美日韩在线高清直播| 日韩欧美主播在线| 国产亚洲欧洲一区高清在线观看| 国产女同性恋一区二区| 欧美日韩中文另类| 污污视频在线看| 视频在线一区二区| 九九久久99| 在线视频你懂得一区| 情事1991在线| 国产精品密蕾丝视频下载| 国产精品免费一区二区三区四区| 久久亚洲资源| 一区二区亚洲欧洲国产日韩| 欧美性猛片xxxx免费看久爱| 国产精品欧美精品| 亚洲无线观看| 日韩不卡在线观看日韩不卡视频| 国产一区不卡视频| 成人在线视频区| 午夜伦全在线观看| 精品一区日韩成人| 亚洲精品国产一区二区精华液| 性做久久久久久| 96sao精品视频在线观看| 国产精品一区三区在线观看| 国产1区2区3区在线| 精品偷拍各种wc美女嘘嘘| 不卡一区2区| 性做久久久久久| 欧美日韩亚洲综合| 国产亚洲精品综合一区91| 国产精品久久久久久久久久久久久久| 国产欧美一区二区三区久久| 欧美在线观看一区二区三区| 一本久久知道综合久久| 伊人精品综合| 久久狠狠一本精品综合网| 麻豆精品在线看| 色呦呦网站在线观看| 国产suv一区二区三区88区| 国产精品亚洲精品| 亚洲成色最大综合在线| 色综合天天综合色综合av| 老牛影视av一区二区在线观看| 国产一区二区按摩在线观看| 国产综合久久久久久久久久久久| 97在线精品视频| 自拍视频在线观看一区二区| 岛国av一区二区三区| 国产**成人网毛片九色| 欧美性xxxxxx少妇| 亚瑟在线精品视频| 亚洲另类春色校园小说| 亚洲精品国产精品国自产观看浪潮| 亚洲丝袜av一区| 日韩精品大片| 美腿丝袜亚洲图片| 欧美视频一区二区三区| 日韩激情图片| 亚洲高清免费观看| 久久这里只精品最新地址| 中文在线最新版地址| 欧美福利视频一区| 精品久久一区二区三区蜜桃| yellow视频在线观看一区二区| 亚洲国产精品va在线观看黑人| 欧美日韩国产中字| 91精品综合久久久久久五月天| 日韩专区在线观看| 国产精品免费网站| 国产一区二区三区在线看麻豆| www.丝袜精品| 93在线视频精品免费观看| 中文字幕亚洲欧美日韩高清| 亚洲免费成人| 国产精品久久久av久久久| 日韩精品专区在线影院重磅| 国产精品久久久久久久一区探花| 国产乱码精品一区二三赶尸艳谈| 91av在线精品| 日韩欧美在线观看视频| 久久激情五月婷婷| 99视频精品在线| 午夜a一级毛片亚洲欧洲| 亚洲精品中文综合第一页| 国产成人三级在线观看| 国产日韩欧美中文| 亚洲精品一线| 激情综合亚洲| 欧美日韩xxx| 岛国一区二区在线观看| 欧美激情国产高清| 国内一区二区视频| 99久久久久久| 亚洲麻豆av| 欧美精品第一页在线播放| 少妇高潮久久久久久潘金莲| 欧美视频专区一二在线观看| 精品一区二区三区国产| a级毛片免费观看在线| 国产在线一区二区三区播放| 欧美aa视频| 亚洲欧美成人精品| 台湾佬成人网| 国产一区二中文字幕在线看| 国产一区二区区别| 久久久久久国产精品mv| 日本精品一区二区三区不卡无字幕| 亚洲一区自拍偷拍| 2014亚洲片线观看视频免费| 日韩福利视频一区| 粉嫩av免费一区二区三区| 欧美日韩一区二区三区在线视频| 国产精品18久久久久久久久久久久| 亚洲高清视频一区二区| 欧美一区二区视频17c| 国产一区亚洲一区| 色噜噜狠狠色综合欧洲selulu| 国产成人午夜精品影院观看视频| 欧美精品在线一区二区三区| 七七婷婷婷婷精品国产| 视频一区在线免费观看| 综合一区av| 欧美一区二区三区免费视| 欧美在线啊v一区| 久久久久国色av免费看影院| 亚洲综合在线五月| 精品人伦一区二区色婷婷| 先锋影音网一区二区| 久久动漫网址| 全亚洲第一av番号网站| 国产伦精品一区二区三区千人斩| 国产日本亚洲高清| 亚洲在线国产日韩欧美| 久久久91精品国产一区二区三区| 成人精品一区二区三区中文字幕| 国产网站在线免费观看| 1000精品久久久久久久久| 大胆欧美人体视频| 国产精品午夜国产小视频| 国产精品久av福利在线观看| 中文字幕日韩av电影| 一个人www视频在线免费观看| 精品一二线国产| 伊人精品在线观看| 粉嫩一区二区三区在线观看| 欧美一区二区三区图|