整合營銷服務(wù)商

          電腦端+手機(jī)端+微信端=數(shù)據(jù)同步管理

          免費(fèi)咨詢熱線:

          SVG在Web攻擊中的應(yīng)用

          SVG在Web攻擊中的應(yīng)用

          x00 前言

          在過去幾周中,F(xiàn)ortiGuard Labs一直在研究帶有SVG(Scalable Vector Graphics)圖像的Web應(yīng)用。根據(jù)研究結(jié)果,我們找到了Web應(yīng)用中的一些常見問題。在本文中,我們簡要介紹了SVG的特點(diǎn)以及針對SVG圖像的常見攻擊面。

          根據(jù)之前的研究結(jié)果,我們梳理了一些常見的SVG攻擊方式,如下所示:

          • 跨站腳本(Cross-Site Scripting)
          • HTML注入
          • XML實(shí)體:“Billion Laughs”攻擊(針對XML文檔解析器的一種DoS攻擊)
          • DoS(拒絕服務(wù)):新型SVG “Billion Laughs”攻擊。

          0x01 SVG簡介

          SVG的全稱為 Scalable Vector Graphics(可縮放矢量圖),是一種基于XML的二維矢量圖格式,支持交互性及動畫展示。SVG圖像及具體行為由XML文本文件定義,可以通過任何文本編輯器以及繪圖軟件來創(chuàng)建并編輯。目前所有主流web瀏覽器都支持渲染SVG圖像。

          來觀察一個示例,更好理解SVG圖像。如下圖所示,我們編寫了一些代碼來渲染SVG圖像:

          圖1. simple.svg代碼片段

          將該圖像保存為simple.svg,然后直接打開,或者將其包含在img/image/object/embed HTML標(biāo)簽中,如下圖所示:

          圖2. 通過代碼渲染圖像

          圖1代碼渲染生成的圖像如圖2所示,這是rect元素,瀏覽器會在x, y (100, 100)(即寬度和高度)位置渲染一個紅色矩形。

          0x02 使用SVG的攻擊場景

          雖然SVG提供了較大的靈活性,可以方便創(chuàng)建更多的動態(tài)web內(nèi)容,但同時也引入了一些安全風(fēng)險(xiǎn)。在下文中,我們將討論一些常見的攻擊向量,我們在互聯(lián)網(wǎng)上的一些主流站點(diǎn)上都觀察到過這些攻擊方式。

          跨站腳本

          我們可以通過腳本方式來訪問并修改SVG文檔的任何內(nèi)容,這與HTML操作方式類似。默認(rèn)的腳本語言為ECMAScript(與JavaScript密切相關(guān)),每個SVG元素及屬性都對應(yīng)已定義的DOM(Document Object Model,文檔對象模型)對象。相關(guān)腳本被封裝在<script>元素中。

          這意味著如果web服務(wù)器允許用戶上傳任意SVG圖像,就存在XSS(跨站腳本)安全風(fēng)險(xiǎn)。如下所示,我們將腳本存放在圖像中:

          圖3. xss.svg代碼片段

          將該圖像保存為xss.svg,然后直接打開,如下圖所示:

          圖4. 直接訪問該文件觸發(fā)XSS

          如果將該文件鏈接到某個HTML頁面,訪問該頁面也可以觸發(fā),如下圖所示:

          圖5. 通過鏈接文件觸發(fā)XSS

          JavaScript代碼會在瀏覽器上下文中執(zhí)行,這意味著攻擊者可以使用該文件執(zhí)行惡意行為,比如竊取用戶隱私信息等。

          HTML注入

          在某些情況下,XSS payload會被服務(wù)端過濾,然而我們依然能夠通過SVG圖像的特定功能來注入HTML代碼。如前文所述,SVG是基于XML的一種矢量圖,因此我們無法簡單將HTML內(nèi)容放入其中,不然會破壞XML的語法。

          為了避免這種情況,SVG提供了一個foreignObject元素,可以用來包含來自其他XML命名空間的元素。在瀏覽器上下文中,這部分?jǐn)?shù)據(jù)很可能采用(X)HTML形式。

          來看一下html.svg圖像:

          圖6. html.svg代碼片段

          當(dāng)我們在foreignObject內(nèi)添加一個body標(biāo)簽以及XHTML命名空間時,可以使用xmlns屬性來聲明命名空間。采用這種方式,瀏覽器會將body標(biāo)簽及其所有子標(biāo)簽解析為屬于XHTML的元素。因此,我們可以將來自SVG的任意XHTML代碼渲染到頁面中:

          圖7. HTML注入漏洞

          這種方式可以運(yùn)行任意HTML代碼,意味著我們可以簡單從SVG圖像中發(fā)起類似釣魚、繞過同源策略、CSRF之類的攻擊。

          XML實(shí)體:Billion Laughs Attack

          由于SVG是基于XML的矢量圖,因此可以支持Entity(實(shí)體)功能。Entity可以用來定義特殊字符的快捷方式,也可以聲明成內(nèi)部或外部實(shí)體。

          我們可以通過如下方式聲明內(nèi)部Entity:

          <!ENTITY entity-name "entity-value">
          

          通過如下方式聲明外部Entity:

          <!ENTITY entity-name SYSTEM "URI/URL">
          

          如果解析文件的XML解析器存在脆弱性,那么我們就可以濫用外部Entity功能來泄露內(nèi)部數(shù)據(jù)。由于現(xiàn)在大家主要使用的都是現(xiàn)代瀏覽器,因此我們假設(shè)可用的解析器都經(jīng)過fuzzer的嚴(yán)格測試,因此沒那么容易被攻擊。在這個前提下,這里我們主要討論如何濫用內(nèi)部Entity。

          entity.svg的內(nèi)部實(shí)現(xiàn)如下所示:

          圖8. entity.svg代碼片段

          如上圖所示,我們在第2行定義lab這個Entity,然后在SVG元素中調(diào)用該實(shí)體。結(jié)果如圖9所示:

          圖9. lab實(shí)體被加載到頁面

          一切非常順利,來嘗試另一個例子:entity_2.svg,如下圖所示:

          圖10. entity_2.svg代碼片段

          結(jié)果如下:

          圖11. lab2實(shí)體被加載到頁面

          如上圖所示,這里的文本內(nèi)容被重復(fù)渲染,這表明我們可以使用Entity標(biāo)簽發(fā)起“ Billion Laughs ”攻擊。

          “ Billion Laughs ”攻擊是一種DoS(拒絕服務(wù))攻擊,目標(biāo)是XML文檔解析器。這種攻擊也被稱之為XML炸彈或者指數(shù)實(shí)體攻擊。

          圖12. billion_laughs.svg代碼片段

          我們的瀏覽器在解析這個 billion_laughs.svg數(shù)據(jù)時,只花了4~5秒就能正常響應(yīng)。這是因?yàn)榇蠖鄶?shù)現(xiàn)代瀏覽器已經(jīng)能夠能應(yīng)付這種攻擊,可以在渲染過程中解決該問題,因此不會造成安全風(fēng)險(xiǎn)。

          拒絕服務(wù):新型SVG “Billion Laughs”攻擊

          在上一節(jié)中,我們發(fā)現(xiàn)“ Billion Laughs ”攻擊可以延緩瀏覽器的處理速度,瀏覽器需要4~5秒才能應(yīng)付該攻擊。不幸的是,攻擊者還可以通過SVG圖像,發(fā)起另一種“ Billion Laughs ”攻擊,繞過這些防御措施。

          這一次我們使用xlink:href來代替XML Entity。來看一下 xlink_laughs.svg所使用的payload:

          圖13. xlink_laughs.svg代碼片段

          xlink:href屬性以IRI(國際資源標(biāo)識)方式定義了對某個資源的引用,該鏈接的具體含義需根據(jù)使用該鏈接的每個元素的上下文來決定。

          <use>元素從SVG文檔中獲取節(jié)點(diǎn),然后將其復(fù)制到其他位置。

          我們現(xiàn)在a0中定義circle元素,然后在a1、a2、a3……中通過xlink:href屬性調(diào)用<use>元素,通過這種方式反復(fù)克隆circle。結(jié)果如下圖所示:

          圖14. 在解析惡意SVG時,通過xlink:href發(fā)起“ Billion Laugh”攻擊

          需要注意的是,在最壞的情況下,大多數(shù)現(xiàn)代瀏覽器在嘗試解析網(wǎng)站上的這張SVG圖像時可能會發(fā)生崩潰,或者至少會出現(xiàn)無響應(yīng)情況。

          有趣的是,我們在測試某些開源SVG/XML過濾器時,發(fā)現(xiàn)這些過濾器并不能正確捕捉到圖13所示的SVG圖像。因此,這種錯誤格式的SVG圖像也可能造成DoS效果。

          0x03 總結(jié)

          SVG圖像更像HTML,而不單單是一張簡單的圖像。因此,我們建議web開發(fā)者盡可能不要以對象或者iframe形式加載任何SVG。Web管理員同樣應(yīng)當(dāng)限制可以上傳到站點(diǎn)的文件類型。

          此外,任何不可信的SVG圖像在被上傳到服務(wù)端前都必須經(jīng)過過濾處理,可以采取如下操作:

          • 限制危險(xiǎn)標(biāo)簽,比如script、foreignObject等。
          • 限制通過SVG圖像的外部鏈接加載資源。
          • 限制SVG圖像內(nèi)的擴(kuò)展邏輯。

          我們使用一些瀏覽器來直接打開這些惡意SVG文件,對比結(jié)果如下圖所示:

          大家可以訪問我們的Github倉庫下載本文使用的SVG樣本。

          0x04 參考資料

          [1] W3C, “Scalable Vector Graphics” https://www.w3.org/TR/SVG2/ (02 September, 2019)
          [2] OWASP, “The Image that called me” https://www.owasp.org/images/0/03/Mario_Heiderich_OWASP_Sweden_The_image_that_called_me.pdf (02 September, 2019)
          [3] Blackhat, “Exploiting Browsers without Image Parsing Bugs” https://www.blackhat.com/docs/us-14/materials/us-14-DeGraaf-SVG-Exploiting-Browsers-Without-Image-Parsing-Bugs.pdf (02 September, 2019)

          原文鏈接:https://www.anquanke.com/post/id/190651

          我們閱讀這篇文章之前,我們需要思考下,我們?yōu)槭惨チ私釹VG,閱讀了這篇文章是否可以給我們帶來幫助。

          1. 如果你想要一張 css或者JavaScript可以控制的圖片,那么你可以考慮SVG。

          2. 如果你期望圖片的質(zhì)量不會因?yàn)榉糯蠡蚩s小而降低,那么你可以考慮SVG。

          3. 如果你期望網(wǎng)頁對殘障人士和視力受損的用戶有更好的體驗(yàn),那么你可以考慮SVG。

          4. 如果你期望圖片在高清設(shè)備還是低分辨率設(shè)備上,都能保持清晰和細(xì)膩的圖像質(zhì)量,那么你可以考慮SVG。

          1. 矢量圖

          我們在學(xué)習(xí)SVG之前,需要先了解一下位圖和矢量圖。

          簡單來說:

          • 位圖:由像素點(diǎn)組成的圖像,放大圖像會失真,canvas就是位圖效果。
          • 矢量圖:由數(shù)學(xué)公式(通常是XML)來描述圖像,放大圖像不會失真。

          詳細(xì)來說:

          • 位圖:也稱為像素圖,是由一個個像素點(diǎn)組成的圖像。每個像素點(diǎn)都有特定的顏色和位置,這些信息被編碼并存儲在文件中。位圖的顯示效果取決于像素的數(shù)量和密度,即分辨率。一般來說,位圖主要用于表示細(xì)節(jié)豐富,顏色和亮度變化多的圖像,如照片,自然風(fēng)景等。
          • 矢量圖:使用數(shù)學(xué)公式(通常是XML)來描述圖像,而不是像位圖那樣使用像素矩陣。這些數(shù)據(jù)公式?jīng)Q定了圖像的形狀,線條和填充樣式。由于矢量圖的每個元素都是由數(shù)學(xué)公式定義的,因此它們可以在不同尺寸和分辨率下保持清晰度。這種類型的圖像在縮放,旋轉(zhuǎn)或以其他方式變換時不會失去細(xì)節(jié)或者質(zhì)量。

          2. SVG

          SVG究竟什么?

          是Scalable Vector Graphics的縮寫,意思是可縮放矢量圖形。

          這是一種基于XML的二維矢量圖形標(biāo)準(zhǔn),由W3C開發(fā)的。

          對于初學(xué)者來說,可以將SVG理解為一套新的HTML標(biāo)簽。

          所以我們可以使用css和JavaScript來對標(biāo)簽進(jìn)行操作。

          很多小伙伴可能已經(jīng)忘記了XML,我們回顧一下:
          XML(可擴(kuò)展標(biāo)記語言)是一種用于描述數(shù)據(jù)的標(biāo)記語言,它使用一系列簡單的標(biāo)記來描述數(shù)據(jù),這些標(biāo)記可以用來表示不同類型的數(shù)據(jù)元素,如標(biāo)題,作者,價(jià)格等。

          3. 優(yōu)勢

          SVG的優(yōu)勢:

          1. 可擴(kuò)展性和響應(yīng)能力:SVG是使用形狀,數(shù)字和坐標(biāo)在瀏覽器中渲染圖形,這使得它具有分辨率無關(guān)性和無限可伸縮性。不管我們畫了什么圖形,不論用戶將頁面放的多大,圖形都不會失真,只是比例變化了而已。
          2. 可編程性和交互性:SVG是完全可編輯和腳本可編寫的,我們可以通過css和JavaScript將各種動畫和交互添加到繪圖中。
          3. 無障礙:SVG文件是基于文本的,可以進(jìn)行搜索和索引,這使得他們可以通過屏幕閱讀器,搜索引擎和其他設(shè)備閱讀。
          4. 性能:與GIF,JPG和PNG相比,SVG通常是較小的文件。

          4. 劣勢

          SVG的劣勢:

          設(shè)計(jì)復(fù)雜性:SVG需要具備一定的設(shè)計(jì)和制作技巧,與位圖相比,SVG的設(shè)計(jì)難度較大,需要更高的技術(shù)水平。

          瀏覽器兼容性:在一些舊版瀏覽器中,可能存在對SVG的兼容性問題。

          渲染速度:SVG復(fù)雜度過高會降低頁面渲染速度。

          5. 使用方式

          對于前端開發(fā)的我們,要如何去使用SVG呢?

          SVG歸根結(jié)底來說和JPG,PNG一樣,也是一種圖像格式,所以我們可以在HTML中,將SVG的路徑設(shè)置為<img>的src屬性。

          我們也可以將SVG的代碼放在HTML中,我們完全可以把SVG的代碼看做成我們的HTML標(biāo)簽。

          例如:

          <svg width="500" height="500">
              <circle cx="100" cy="100" r="50" fill="transparent" stroke="#000"></circle>
          </svg>
          

          我們也可以通過css的background-image或者偽元素,將SVG圖片作為背景圖像。

          6. 使用場景

          1. 圖標(biāo)和徽標(biāo):由于SVG可以無損縮放,所以非常適合用來做網(wǎng)站的圖標(biāo)和徽標(biāo),無論是在大屏幕還是小屏幕上,SVG都能保證清晰度。
          2. 插畫:任何鋼筆或鉛筆制作的傳統(tǒng)繪圖,都可以完美轉(zhuǎn)化為SVG格式。
          3. 動態(tài)圖形:SVG的腳本特性使它可以用來創(chuàng)建動態(tài)的,交互式圖形。
          4. 之前我做過空調(diào)的SVG圖片,然后由JavaScript控制空調(diào)上的開關(guān),溫度,模式。
          5. 地圖和圖表:SVG可以繪制地圖和圖表,然后和JavaScript進(jìn)行數(shù)據(jù)交互。
          6. 游戲:雖然SVG不是專門用來做游戲的,但是一些游戲開發(fā)者會用SVG來制作游戲中的圖形。

          總的來說,任何需要保持清晰度,動態(tài)交互和無損縮放的圖形場景,都可以考慮使用SVG。

          7. Canvas與SVG

          Canvas和SVG都是用于在網(wǎng)頁上繪制圖形的工具,但它們在許多方面都存在顯著的差異。以下是對Canvas和SVG的對比:

          1. 基本概念
          2. Canvas:是HTML5提供的 <canvas>標(biāo)簽,使用JavaScript在網(wǎng)頁上繪制圖形。它主要通過像素進(jìn)行渲染,不支持事件處理器。
          3. SVG:全稱為可伸縮矢量圖形(Scalable Vector Graphics),是基于XML的二維圖形語言。它由許多節(jié)點(diǎn)構(gòu)成,每個被繪制的圖形都被視為一個對象,如果SVG對象的屬性發(fā)生變化,瀏覽器能夠自動重現(xiàn)圖形。
          4. 特點(diǎn)
          5. Canvas: 依賴分辨率。 不支持事件處理器。 弱的文本渲染能力。 能夠以 .png 或 .jpg 格式保存結(jié)果圖像。 最適合圖像密集型的游戲,其中的許多對象會被頻繁重繪。
          6. SVG: 基于矢量,能夠很好地處理圖形大小的改變。 不支持事件處理器。 弱的文本渲染能力。 能夠以 .png 或 .jpg 格式保存結(jié)果圖像。
          7. 性能
          8. Canvas的歷史沒有SVG悠久,它是H5新增的標(biāo)簽,而SVG已經(jīng)存在十幾年。
          9. SVG圖形節(jié)點(diǎn)足夠多時,渲染會比較慢,而Canvas性能好一些。
          10. 其他差異
          11. Canvas適合帶有大型渲染區(qū)域的應(yīng)用程序(如谷歌地圖)。
          12. SVG的復(fù)雜度高可能會減慢渲染速度(任何過度使用DOM的應(yīng)用都不快)。

          總結(jié):Canvas和SVG各有其優(yōu)勢和適用場景。Canvas更適合圖像密集型的游戲和需要高效渲染的應(yīng)用,而SVG更適合處理矢量圖形和大型渲染區(qū)域。

          8. 實(shí)戰(zhàn)一

          說了這么多,我們來開始實(shí)戰(zhàn),我們要在HTML中,畫出一個SVG圖像。

          <html>
          <body>
          <h1>Feng SVG</h1>
          
          <svg version="1.1"  baseProfile="full"  width="300" height="200"  xmlns="http://www.w3.org/2000/svg">
            <rect width="100%" height="100%" stroke="red" stroke-width="4" fill="yellow" />
            <circle cx="150" cy="100" r="80" fill="green" />
            <text x="150" y="115" font-size="16" text-anchor="middle" fill="white">RUNOOB SVG TEST</text>
          </svg> 
          
          </body>
          </html>
          

          運(yùn)行后:

          代碼解讀:

          1. <svg>和</svg>是表示SVG代碼,相當(dāng)于開始標(biāo)簽和結(jié)束標(biāo)簽,這是根元素。
          2. width 和 height 屬性可設(shè)置此 SVG 的寬度和高度。
          3. version 屬性可定義所使用的 SVG 版本。
          4. xmlns 屬性可定義 SVG 命名空間。
          5. baseProfile 特性描述了作者認(rèn)為正確渲染內(nèi)容所需要的最小的 SVG 語言概述。這個特性不會說明任何處理限制,可以把它看作是元數(shù)據(jù)。
          6. SVG 的 <rect> 用來創(chuàng)建一個矩形,通過 fill 把背景顏色設(shè)為黃色。
          7. SVG 的 <circle> 用來創(chuàng)建一個圓。cx 和 cy 屬性定義圓中心的 x 和 y 坐標(biāo)。如果忽略這兩個屬性,那么圓點(diǎn)會被設(shè)置為 (0, 0),r 屬性定義圓的半徑。 一個半徑 80px 的綠色圓圈 <circle> 繪制在紅色矩形的正中央 (向右偏移 150px,向下偏移115px)。
          8. stroke 和 stroke-width 屬性控制如何顯示形狀的輪廓。我們把圓的輪廓設(shè)置為 4px 寬,紅色邊框。
          9. fill 屬性設(shè)置形狀內(nèi)的顏色。我們把填充顏色設(shè)置為紅色。

          9. 實(shí)戰(zhàn)二

          我們還可以在線設(shè)計(jì)SVG圖片,我們可以直接使用該圖片或者拷貝其代碼復(fù)制到我們的代碼中。

          SVG在線編輯: c.runoob.com/more/svgedi…

          10. SVG的基本形狀

          10.1 矩形

          示例一

          正常的矩形

          <svg xmlns="http://www.w3.org/2000/svg" version="1.1">
            <rect width="300" height="100" style="fill:rgb(122,122,0);stroke-width:2;stroke:rgb(0,0,0)" />
          </svg>
          
          

          效果:

          代碼解析:

          • <rect>:這是一個矩形元素,用于在SVG圖像中繪制矩形。
          • width="300" 和 height="100":這兩個屬性定義了矩形的寬度和高度。在這個例子中,矩形的寬度是300像素,高度是100像素。
          • style="fill:rgb(122,122,0);stroke-width:2;stroke:rgb(0,0,0)":這設(shè)置了矩形的樣式。 fill:rgb(122,122,0):設(shè)置填充顏色為RGB值(122,122,0)的顏色,這是一種黃色調(diào)的顏色。 stroke-width:2:設(shè)置線條寬度為2像素。 stroke:rgb(0,0,0):設(shè)置線條顏色為RGB值(0,0,0)的顏色,這是一種黑色。

          綜上,這段代碼會在SVG圖像中繪制一個寬度為300像素、高度為100像素、填充顏色為黃色調(diào)、線條寬度為2像素、線條顏色為黑色的矩形。

          示例二:

          填充和邊框的透明度

          <svg xmlns="http://www.w3.org/2000/svg" version="1.1">
            <rect x="50" y="20" width="150" height="150" style="fill:blue;stroke:red;stroke-width:5;fill-opacity:0.5;stroke-opacity:0.5" />
          </svg>
          
          

          效果:

          代碼解析:

          • <rect>:這是一個矩形元素,用于在SVG圖像中繪制矩形。
          • x="50" 和 y="20":這兩個屬性定義了矩形左上角的坐標(biāo)(x, y)。在這個例子中,坐標(biāo)是(50, 20)。
          • width="150" 和 height="150":這兩個屬性定義了矩形的寬度和高度。在這個例子中,矩形的寬度是150像素,高度是150像素。
          • style="fill:blue;stroke:red;stroke-width:5;fill-opacity:0.5;stroke-opacity:0.5":這設(shè)置了矩形的樣式。 fill:blue:設(shè)置填充顏色為藍(lán)色。 stroke:red:設(shè)置線條顏色為紅色。 stroke-width:5:設(shè)置線條寬度為5像素。 fill-opacity:0.5:設(shè)置填充透明度為0.5,這意味著矩形將是半透明的。 stroke-opacity:0.5:設(shè)置線條透明度為0.5,這意味著線條將是半透明的。

          綜上,這段代碼會在一個SVG圖像中繪制一個左上角坐標(biāo)為(50, 20)、寬度為150像素、高度為150像素、填充顏色為藍(lán)色、線條顏色為紅色、線條寬度為5像素、填充透明度和線條透明度都為0.5的矩形。

          示例三:

          整個元素的透明度

          <svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="500px" height="500px">
            <rect x="50" y="20" width="150" height="150" style="fill:blue;stroke:pink;stroke-width:5;opacity:0.4" />
          </svg>
          

          效果:

          代碼解析:

          • <rect>:這是一個矩形元素,用于在SVG圖像中繪制矩形。
          • x="50" 和 y="20":這兩個屬性定義了矩形左上角的坐標(biāo)(x, y)。在這個例子中,坐標(biāo)是(50, 20)。
          • width="150" 和 height="150":這兩個屬性定義了矩形的寬度和高度。在這個例子中,矩形的寬度是150像素,高度是150像素。
          • style="fill:blue;stroke:pink;stroke-width:5;opacity:0.4":這設(shè)置了矩形的樣式。 fill:blue:設(shè)置填充顏色為藍(lán)色。 stroke:pink:設(shè)置線條顏色為粉紅色。 stroke-width:5:設(shè)置線條寬度為5像素。 opacity:0.4:設(shè)置透明度為0.4,這意味著矩形將是半透明的。

          綜上,這段代碼會在一個500x500像素的SVG圖像中繪制一個左上角坐標(biāo)為(50, 20)、寬度為150像素、高度為150像素、填充顏色為藍(lán)色、線條顏色為粉紅色、線條寬度為5像素、透明度為0.4的矩形。

          示例四:

          圓角矩形

          <svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="500px" height="500px">
            <rect x="50" y="20" rx="20" ry="20" width="150" height="160" style="fill:red;stroke:black;stroke-width:1;opacity:0.5" />
          </svg>
          

          效果:

          代碼解析:

          • <rect>:這是一個矩形元素,用于在SVG圖像中繪制矩形。
          • x="50" 和 y="20":這兩個屬性定義了矩形左上角的坐標(biāo)(x, y)。在這個例子中,坐標(biāo)是(50, 20)。
          • rx="20" 和 ry="20":這兩個屬性定義了矩形的圓角半徑。在這個例子中,矩形的圓角半徑是20像素。
          • width="150" 和 height="160":這兩個屬性定義了矩形的寬度和高度。在這個例子中,矩形的寬度是150像素,高度是160像素。
          • style="fill:red;stroke:black;stroke-width:1;opacity:0.5":這設(shè)置了矩形的樣式。 fill:red:設(shè)置填充顏色為紅色。 stroke:black:設(shè)置線條顏色為黑色。 stroke-width:1:設(shè)置線條寬度為1像素。 opacity:0.5:設(shè)置透明度為0.5,這意味著矩形將是半透明的。

          綜上,這段代碼會在一個500x500像素的SVG圖像中繪制一個左上角坐標(biāo)為(50, 20)、寬度為150像素、高度為160像素、填充顏色為紅色、線條顏色為黑色、線條寬度為1像素、透明度為0.5的圓角矩形。

          10.2 圓形

          示例:

          <svg xmlns="http://www.w3.org/2000/svg" version="1.1">
             <circle cx="100" cy="50" r="40" stroke="red" stroke-width="2" fill="blue" />
          </svg> 
          

          效果:

          代碼解析:

          • <circle>:這是一個圓形元素,用于在SVG圖像中繪制圓形。
          • cx="100" 和 cy="50":這兩個屬性定義了圓心的坐標(biāo)(x, y)。在這個例子中,圓心的坐標(biāo)是(100, 50)。
          • r="40":這個屬性定義了圓的半徑,單位是像素。在這個例子中,圓的半徑是40像素。
          • stroke="red":這個屬性定義了圓的邊框顏色。在這個例子中,圓的邊框顏色是紅色。
          • stroke-width="2":這個屬性定義了圓的邊框?qū)挾取T谶@個例子中,圓的邊框?qū)挾仁?像素。
          • fill="blue":這個屬性定義了圓的填充顏色。在這個例子中,圓的填充顏色是藍(lán)色。

          綜上,這段代碼會在一個SVG圖像中繪制一個圓心坐標(biāo)為(100, 50)、半徑為40像素、邊框顏色為紅色、邊框?qū)挾葹?像素、填充顏色為藍(lán)色的圓形。

          10.3 橢圓

          示例:

          <svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="500" height="500">
            <ellipse cx="300" cy="80" rx="100" ry="50" style="fill:red;stroke:purple;stroke-width:2" />
          </svg>
          

          效果:

          代碼解析:

          • <ellipse>:這是一個橢圓元素,用于在SVG圖像中繪制橢圓。
          • cx="300" 和 cy="80":這兩個屬性定義了橢圓的中心點(diǎn)坐標(biāo)(x, y)。在這個例子中,中心點(diǎn)坐標(biāo)是(300, 80)。
          • rx="100" 和 ry="50":這兩個屬性定義了橢圓的長軸和短軸半徑。在這個例子中,長軸半徑是100像素,短軸半徑是50像素。
          • style="fill:red;stroke:purple;stroke-width:2":這設(shè)置了橢圓的樣式。 fill:red:設(shè)置填充顏色為紅色。 stroke:purple:設(shè)置線條顏色為紫色。 stroke-width:2:設(shè)置線條寬度為2像素。

          綜上,這段代碼會在一個500x500像素的SVG圖像中繪制一個中心點(diǎn)坐標(biāo)為(300, 80)、長軸半徑為100像素、短軸半徑為50像素的紅色橢圓,線條顏色為紫色,線條寬度為2像素。

          10.4 線

          示例:

          <svg xmlns="http://www.w3.org/2000/svg" version="1.1">
            <line x1="0" y1="0" x2="200" y2="200" style="stroke:black;stroke-width:5" />
          </svg>
          

          效果:

          代碼解析:

          • <line>:這是一個線段元素,用于在SVG圖像中繪制線段。
          • x1="0" 和 y1="0":這兩個屬性定義了線段的起始點(diǎn)坐標(biāo)(x, y)。在這個例子中,起始點(diǎn)坐標(biāo)是(0, 0)。
          • x2="200" 和 y2="200":這兩個屬性定義了線段的終點(diǎn)坐標(biāo)(x, y)。在這個例子中,終點(diǎn)坐標(biāo)是(200, 200)。
          • style="stroke:black;stroke-width:5":這設(shè)置了線段的樣式。 stroke:black:設(shè)置線條顏色為黑色。 stroke-width:5:設(shè)置線條寬度為5像素。

          綜上,這段代碼會在一個SVG圖像中繪制一條從(0, 0)到(200, 200)的黑色線段,線條寬度為5像素。

          11.5 折線

          示例一:

          <svg xmlns="http://www.w3.org/2000/svg" version="1.1">
            <polyline points="20,20 40,25 60,40 80,10 120,140 200,180" style="fill:none;stroke:black;stroke-width:3" />
          </svg>
          

          效果:

          代碼解析:

          • <polyline>:這是一個多邊形線條元素,它使用points屬性定義多邊形的頂點(diǎn)。
          • points="20,20 40,25 60,40 80,10 120,140 200,180":這定義了多邊形的頂點(diǎn)。每個頂點(diǎn)由兩個坐標(biāo)值(x和y)組成,它們之間用空格分隔,并且每個頂點(diǎn)之間用空格分隔。例如,20,20定義了一個頂點(diǎn)在(20,20)的位置。
          • style="fill:none;stroke:black;stroke-width:3":這設(shè)置了多邊形的樣式。 fill:none:設(shè)置填充顏色為透明(不填充)。 stroke:black:設(shè)置線條顏色為黑色。 stroke-width:3:設(shè)置線條寬度為3像素。

          綜上,這段代碼會在一個SVG圖像中繪制一個黑色的折線。這個折線有6個點(diǎn),形狀大致為一個不規(guī)則的六邊折線。注意:因?yàn)樵O(shè)置了fill:none,所以該多邊形線段不會進(jìn)行填充,只顯示其黑色邊框。

          示例二:

          畫一個五角星

          <svg style="height:300px;width:300px;" xmlns="http://www.w3.org/2000/svg" version="1.1">
              <polyline points="100 10,40 180,190 60,10 60,160 180" style="fill:blue;stroke:blue;stroke-width:1" />
          </svg>
          
          

          效果:

          代碼解析:

          • <polyline>:這是一個多邊形線條元素,它使用points屬性定義多邊形的頂點(diǎn)。
          • points="100 10,40 180,190 60,10 60,160 180":這定義了多邊形的頂點(diǎn)。每個頂點(diǎn)由兩個坐標(biāo)值(x和y)組成,它們之間用空格分隔,并且每個頂點(diǎn)之間用逗號分隔。例如,100 10定義了一個頂點(diǎn)在(100,10)的位置。
          • style="fill:blue;stroke:blue;stroke-width:1":這設(shè)置了多邊形的樣式。 fill:blue:設(shè)置填充顏色為藍(lán)色。 stroke:blue:設(shè)置線條顏色為藍(lán)色。 stroke-width:1:設(shè)置線條寬度為1像素。

          綜上,這段代碼會在一個300x300像素的區(qū)域內(nèi)繪制一個藍(lán)色的多邊形。這個多邊形有5個頂點(diǎn),形狀大致為一個不規(guī)則的五邊形。

          10.6 多邊形

          示例一:

          <svg  height="210" width="500">
            <polygon points="200,10 250,190 160,210"
            style="fill:red;stroke:purple;stroke-width:1"/>
          </svg>
          

          效果:

          代碼解析:

          • <polygon>:這是一個多邊形元素,用于在SVG圖像中繪制多邊形。
          • points="200,10 250,190 160,210":這個屬性定義了多邊形的頂點(diǎn)坐標(biāo)。在這個例子中,多邊形有三個頂點(diǎn):(200,10), (250,190) 和 (160,210)。
          • style="fill:red;stroke:purple;stroke-width:1":這設(shè)置了多邊形的樣式。 fill:red:設(shè)置填充顏色為紅色。 stroke:purple:設(shè)置線條顏色為紫色。 stroke-width:1:設(shè)置線條寬度為1像素。

          綜上,這段代碼會在一個500x210像素的SVG圖像中繪制一個由三個頂點(diǎn)定義的多邊形,填充顏色為紅色,線條顏色為紫色,線條寬度為1像素。

          示例二:

          畫一個五角星

          <svg style="height:300px;width:300px;" xmlns="http://www.w3.org/2000/svg" version="1.1">
              <polygon points="100 10,40 180,190 60,10 60,160 180" style="fill:none;stroke:black;stroke-width:5"/>
          </svg>
          
          

          效果:

          代碼解析:

          • <polygon>:這是一個多邊形元素,用于在SVG圖像中繪制多邊形。
          • points="100 10,40 180,190 60,10 60,160 180":這個屬性定義了多邊形的頂點(diǎn)坐標(biāo)。在這個例子中,多邊形有七個頂點(diǎn):(100,10), (40,180), (190,60), (10,60), (160,180)。
          • style="fill:none;stroke:black;stroke-width:5":這設(shè)置了多邊形的樣式。 fill:none:設(shè)置填充顏色為無色。 stroke:black:設(shè)置線條顏色為黑色。 stroke-width:5:設(shè)置線條寬度為5像素。

          綜上,這段代碼會在一個300x300像素的SVG圖像中繪制一個由七個頂點(diǎn)定義的多邊形,沒有填充顏色,線條顏色為黑色,線條寬度為5像素。

          10.7 路徑

          路徑數(shù)據(jù):

          1. M (moveto): 該命令開始一個新的路徑,并設(shè)置當(dāng)前點(diǎn)。其后的命令將從這個點(diǎn)開始繪制線條或曲線。
          2. L (lineto): 該命令從當(dāng)前點(diǎn)繪制一條直線到指定點(diǎn)。
          3. H (horizontal lineto): 該命令從當(dāng)前點(diǎn)繪制一條水平線到指定x坐標(biāo)。y坐標(biāo)保持不變。
          4. V (vertical lineto): 該命令從當(dāng)前點(diǎn)繪制一條垂直線到指定y坐標(biāo)。x坐標(biāo)保持不變。
          5. C (curveto): 該命令繪制一個貝塞爾曲線,需要提供三個點(diǎn):控制點(diǎn)和結(jié)束點(diǎn)。
          6. S (smooth curveto): 該命令繪制一個平滑的貝塞爾曲線,它使用前一個點(diǎn)和當(dāng)前點(diǎn)作為控制點(diǎn),并連接到下一個點(diǎn)。
          7. Q (quadratic Bézier curve): 該命令繪制一個二次貝塞爾曲線,需要提供兩個點(diǎn):控制點(diǎn)和結(jié)束點(diǎn)。
          8. T (smooth quadratic Bézier curveto): 該命令繪制一個平滑的二次貝塞爾曲線,它使用前一個點(diǎn)和當(dāng)前點(diǎn)作為控制點(diǎn),并連接到下一個點(diǎn)。
          9. A (elliptical Arc): 該命令繪制一個橢圓弧,需要提供起始角度、結(jié)束角度、半徑和旋轉(zhuǎn)角度等參數(shù)。
          10. Z (closepath): 該命令關(guān)閉路徑,將當(dāng)前點(diǎn)連接到起始點(diǎn),形成一個封閉圖形。

          示例:

          畫一個三角形

          <svg xmlns="http://www.w3.org/2000/svg" version="1.1">
            <path d="M150 0 L75 200 L205 270 Z" />
          </svg>
          

          效果:

          代碼解析:

          • <path>:這是一個路徑元素,用于繪制線條和曲線。
          • d="M150 0 L75 200 L205 270 Z":這是路徑的指令。這些指令定義了圖形的形狀和位置。 M150 0:移動到(150, 0)點(diǎn)。 L75 200:從當(dāng)前點(diǎn)繪制一條直線到(75, 200)點(diǎn)。 L205 270:從當(dāng)前點(diǎn)繪制一條直線到(205, 270)點(diǎn)。 Z:關(guān)閉路徑,將當(dāng)前點(diǎn)連接到起始點(diǎn),形成一個封閉圖形。

          綜上,這段代碼將在SVG圖像中繪制一個由三個直線段組成的封閉圖形,其頂點(diǎn)坐標(biāo)分別為(150, 0),(75, 200)和(205, 270)。

          11. 設(shè)置樣式

          11.1 屬性樣式

          直接在元素屬性上設(shè)置樣式,比如將矩形填充色改成粉紅

          <svg width="400" height="400" style="border: 1px solid red;">
            <rect
              x="100"
              y="100"
              width="200"
              height="100"
              fill="pink"
            />
          </svg>
          

          11.2 內(nèi)聯(lián)樣式

          把所有樣式寫在 style 屬性里

          <svg width="400" height="400" style="border: 1px solid red;">
            <rect
              x="100"
              y="100"
              width="200"
              height="100"
              style="fill: pink;"
            />
          </svg>
          

          11.3 內(nèi)部樣式

          將樣式寫在 <style> 標(biāo)簽里

          <style>
            .rect {
              fill: pink;
            }
          </style>
          
          <svg width="400" height="400" style="border: 1px solid red;">
            <rect
              x="100"
              y="100"
              width="200"
              height="100"
              class="rect"
            />
          </svg>
          

          11.4 外部樣式

          將樣式寫在 .css 文件里,然后在頁面中引入該 CSS 文件。

          12. SVG動畫

          SVG動畫可以通過多種方式實(shí)現(xiàn),包括使用SMIL、CSS和JavaScript。

          12.1 SMIL

          能讓SVG不靠JavaScript與CSS就能動起來是因?yàn)槭褂昧薙MIL(Synchronized Multimedia Integration Language),是W3C的標(biāo)準(zhǔn)之一,旨在以XML格式提供多媒體的交互表現(xiàn)(白話點(diǎn)其實(shí)就是動畫),是Web上動畫的開路先鋒,啟發(fā)了Web animation與CSS animation。SVG與SMIL的開發(fā)團(tuán)隊(duì)合作,讓SVG能利用SMIL達(dá)到如下效果:

          1. 動畫化元素的數(shù)值屬性
          2. 動畫化元素的transform屬性(平移、旋轉(zhuǎn))
          3. 動畫化元素顏色
          4. 軌跡路線移動動畫,類似于CSS中的offset-path

          光是這些特性就夠我們組合出很多種的動畫了, 使用方法也不難,只要在SVG元素內(nèi)置入以下四種元素即可操作動畫:

          • <set>
          • <animate>
          • <animateTransform>
          • <animateMotion>

          例如:

          <circle cx=“56.7573”cy=“92.8179”r=“2”fill=“black”stroke=“black”stroke-width=“1”>
              <set attributeName=“cy”to=“105.7318”begin=“2s”/>
          </circle>
          

          代碼解析:

          這段代碼用于描述一個圓形,并在特定時間改變其中心點(diǎn)的y坐標(biāo)。

          1. <circle cx="56.7573" cy="92.8179" r="2" fill="black" stroke="black" stroke-width="1" />
          2. <circle>: 這是一個SVG元素,用于繪制一個圓形。
          3. cx="56.7573" 和 cy="92.8179": 定義了圓心的x和y坐標(biāo)。這里,圓心的初始位置是(56.7573, 92.8179)。
          4. r="2": 定義了圓的半徑為2單位。
          5. fill="black": 定義了圓的填充顏色為黑色。
          6. stroke="black": 定義了圓的邊框顏色為黑色。
          7. stroke-width="1": 定義了圓的邊框?qū)挾葹?單位。
          8. <set attributeName="cy" to="105.7318" begin="2s"/>
          9. <set>: 這是一個SVG動畫元素,用于改變元素的屬性。
          10. attributeName="cy": 指定要改變的屬性是cy,即中心點(diǎn)的y坐標(biāo)。
          11. to="105.7318": 指定新的屬性值,即圓心的y坐標(biāo)將變?yōu)?05.7318。
          12. begin="2s": 指定動畫開始的時間,這里表示動畫將在2秒后開始。

          綜上,這段代碼繪制了一個半徑為2單位、填充和邊框顏色均為黑色的圓形,并設(shè)置了一個動畫,使圓心的y坐標(biāo)在2秒后從92.8179變?yōu)?05.7318。

          12.2 基于 CSS 的 SVG 動畫

          通過設(shè)置一組 CSS 樣式和關(guān)鍵幀,可以實(shí)現(xiàn)基于時間或基于事件的 SVG 動畫。這種方式實(shí)現(xiàn)的 SVG 動畫相對簡單,具有易于實(shí)現(xiàn)、可讀性好、易于維護(hù)、性能良好等優(yōu)點(diǎn)。

          下面是一個基于 CSS 的 SVG 動畫示例,實(shí)現(xiàn)了一個圓形的旋轉(zhuǎn)動畫:

          <svg>
            <circle cx="50" cy="50" r="40" />
          </svg>
          
          <style>
            circle {
              fill: red;
              animation: rotate 2s linear infinite;
            }
            @keyframes rotate {
              to {
                transform: rotate(360deg);
              }
            }
          </style>
          

          12.3 基于 JavaScript 的 SVG 動畫

          通過 JavaScript,可以對 SVG 圖形進(jìn)行更加自由和復(fù)雜的動畫操作。JavaScript 可以對 SVG 元素的各種屬性,如位置、大小、顏色、透明度、路徑等進(jìn)行操作,配合定時器和事件監(jiān)聽等方法,實(shí)現(xiàn)豐富多彩的 SVG動畫。

          下面是一個基于 JavaScript 的 SVG 動畫示例,實(shí)現(xiàn)了一個小球自由落體,碰撞彈跳的效果:

          <svg>
            <circle id="ball" cx="50" cy="50" r="20" />
          </svg>
          
          <script>
            let ball=document.querySelector("#ball");
            let startPos=50;
            let endPos=200;
            let speed=3; // 設(shè)置球下落速度
            let gravity=0.2; // 設(shè)置加速度
          
            function moveBall() {
              let pos=parseFloat(ball.getAttribute("cy"));
              let vel=parseFloat(ball.getAttribute("data-vel")) || 0;
          
              // 計(jì)算球的速度和位置
              vel +=gravity;
              pos +=vel * speed;
          
              // 碰撞檢測
              if (pos + 20 > endPos) {
                pos=endPos - 20;
                vel=-vel * 0.8;
              }
          
              // 更新球的位置和速度
              ball.setAttribute("cy", pos);
              ball.setAttribute("data-vel", vel);
          
              // 循環(huán)移動球
              if (pos < endPos - 20) {
                window.requestAnimationFrame(moveBall);
              }
            }
          
            moveBall();
          </script>
          

          13. API一覽表

          14. 總結(jié)

          總的來說,SVG是一種強(qiáng)大的圖形描述語言,具有可縮放性、交互性、可訪問性、靈活性和跨平臺兼容性等特點(diǎn)和優(yōu)勢。它可以用于創(chuàng)建各種復(fù)雜的二維矢量圖形和富交互的Web應(yīng)用,為Web設(shè)計(jì)和開發(fā)提供了更多的可能性。

          隨著Web技術(shù)的不斷發(fā)展,相信SVG的應(yīng)用范圍還將不斷擴(kuò)大。



          原文鏈接:https://juejin.cn/post/7322344486159106100

          下這個例子顯示了,在html中單擊命令按鈕設(shè)定svg中的矩形的填充顏色,并且調(diào)用svg的js函數(shù)FunCallByHtmlJs,產(chǎn)生個消息框。

          在svg中,單擊矩形時,設(shè)置html中的text的文本內(nèi)容,并且調(diào)用html的js函數(shù)FunCallBySvgJs,產(chǎn)生個消息框。

          svg文檔以嵌入在html文檔中運(yùn)行。

          例子在IE 6.0 + Adobe SVG Viewer 3.03中文版下測試通過。

          svg文件的代碼:

          //文件名:Svg&HtmlInteractive.svg

          <svg width="640" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" height="100%" onload="init(evt)" onclick="Click(evt)">

          <script type="text/javascript">

          var svgDoc=null ;

          var svgRoot=null ;

          var parentWnd=null ; //保存html的window對象

          //初始化

          function init(evt)

          {

          svgDoc=evt.target.ownerDocument ;

          svgRoot=svgDoc.documentElement ; //在html中的第二種交互方式會用到

          parentWnd=window.parent ; //ASV 3.0可以這么寫。英文6.0版的要換種寫法

          if(parentWnd.document.title==null || parentWnd.document.title=='')

          {

          alert("請不要直接在瀏覽器中打開'svg'文檔!");

          //下面的代碼作用是不提示確認(rèn)關(guān)閉窗口

          parentWnd.opener=null ;

          parentWnd.open('', '_self') ;

          parentWnd.close() ;

          }

          svgDoc.svgWnd=window ; //這里人為進(jìn)行設(shè)定,以便在html中的第一種交互方式中可以取的到svg的window對象

          }

          function FunCallByHtmlJs()

          {

          alert('這個消息框是在html的js中調(diào)用svg的js函數(shù)產(chǎn)生的。') ;

          }

          function Click(evt)

          {

          var id=evt.target.id ;

          if(id=='rect') //單擊在矩形上,而不是背景上時

          {

          if(parentWnd)

          {

          parentWnd.txt.value='在svg中設(shè)置html中的text的文本內(nèi)容' ;

          parentWnd.FunCallBySvgJs() ; //調(diào)用html中的js函數(shù)

          }

          }

          }

          </script>

          <rect id="background" x="0" y="0" width="100%" height="100%" fill="gray" />

          <rect id="rect" x="50" y="50" width="100" height="100" fill="green" />

          <text font-family="SimSun" font-size="14" fill="yellow" x="50" y="50" id="text">單擊svg的矩形,設(shè)置html的text文本內(nèi)容</text>

          </svg>

          html文件的代碼:

          //文件名:Svg&HtmlInteractive.html

          <html>

          <head>

          <title>SVG與html的交互</title>

          </head>

          <body onload="htmInit()">

          <script type=text/javascript>

          var svgDoc=null;

          var svgRoot=null;

          var svgWnd=null; //svg的window對象

          function htmInit()

          {

          txt.value='';

          }

          function FunCallBySvgJs()

          {

          alert('這個消息框是在svg的js中調(diào)用html的js函數(shù)產(chǎn)生的。');

          }

          function Btn1Clk()

          {

          //第一種方式

          svgDoc=emSvg.getSVGDocument();

          if (svgDoc==null) return;

          svgRoot=svgDoc.documentElement;

          if (svgRoot==null) return;

          var rect=svgRoot.getElementById('rect');

          if(rect) rect.setAttribute('fill', 'blue');

          svgWnd=svgDoc.svgWnd ; //這個window對象是在svg的初始化里面添加進(jìn)去的

          if (svgWnd) svgWnd.FunCallByHtmlJs(); //調(diào)用svg里的js函數(shù)

          }

          function Btn2Clk()

          {

          //第二種方式

          svgWnd=emSvg.window;

          if(svgWnd==null) return;

          svgRoot=svgWnd.svgRoot; //svgRoot在svg的js中是個全局的變量

          if(svgRoot==null) return;

          var rect=svgRoot.getElementById('rect');

          if(rect) rect.setAttribute('fill', 'red');

          svgWnd.FunCallByHtmlJs(); //調(diào)用svg里的js函數(shù)

          }

          </script>

          <input type="button" value="設(shè)置svg中矩形的填充顏色為藍(lán)色" onclick="Btn1Clk()" />

          <input type="button" value="設(shè)置svg中矩形的填充顏色為紅色" onclick="Btn2Clk()" />

          <input id="txt" type="text" value="" />

          <embed id="emSvg" runat="server" src="http://zg672313.blog.163.com/blog/SvgHtmlInteractive.svg" mce_src="http://zg672313.blog.163.com/blog/SvgHtmlInteractive.svg" width="100%" height="95%" wmode="transparent"/>

          </body>

          </html>

          效果圖:

          另外: 在aspx 頁面中,emSvg對象會找不會,應(yīng)該使用 document.getElementById("emSvg") 來查找 SVG對象


          主站蜘蛛池模板: 亚洲一区二区三区国产精华液| 亚洲av成人一区二区三区观看在线| 一区 二区 三区 中文字幕| 蜜臀AV一区二区| 成人精品一区二区电影| 久久精品无码一区二区无码| 亚洲午夜日韩高清一区| 中文字幕亚洲一区| 无码av不卡一区二区三区| 国产SUV精品一区二区88| 国产亚洲一区二区在线观看| 日本一区二区三区高清| 国产一区二区视频在线观看 | 久久se精品一区精品二区| 无码国产精品一区二区免费虚拟VR | 亚洲国产精品成人一区| 中文字幕在线精品视频入口一区| 久久se精品一区二区影院| 综合激情区视频一区视频二区| 国产乱码精品一区二区三区四川人 | 国产凹凸在线一区二区| 国产精品免费综合一区视频| 一区二区三区四区电影视频在线观看| 国产一区二区三区手机在线观看| 国产视频一区在线播放| 国产乱子伦一区二区三区| 日产精品久久久一区二区| 午夜影视日本亚洲欧洲精品一区| 亚洲一区二区三区高清不卡| 手机福利视频一区二区| 在线观看国产区亚洲一区成人 | 国产一区二区三区免费观看在线 | 无码人妻精品一区二区三区99仓本 | 欧美日韩精品一区二区在线视频 | 亚洲福利电影一区二区?| 国产熟女一区二区三区五月婷| 久久国产免费一区二区三区| 成人区人妻精品一区二区不卡视频 | 无码少妇一区二区浪潮av| 一区二区三区四区在线视频| 丰满爆乳一区二区三区|