整合營銷服務商

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

          免費咨詢熱線:

          HTML代碼中的空格和空行

          子1:(文本內容中的連續(xù)空格)

          <p>這段文本中,輸入連續(xù)的空格          大概輸入了十個。</p>

          顯示效果:“格”和“大” 之間的是個空格顯示出來只是一個空格。

          這段文本中,輸入連續(xù)的空格 大概輸入了十個。

          例子2:(代碼之間的連續(xù)空格)

          <span>span是一個行內標簽</span>               <span>和前面的span元素之間隔了很多個空格</span>

          顯示效果:兩個span元素之間連續(xù)的空格,顯示出來即"簽"與“和”之間的空格,只有一個空格。

          span是一個行內標簽 和前面的span元素之間隔了很多個空格

          上面兩個例子證明:HTML代碼中連續(xù)的空格在顯示時會顯示為一個空格,其余的多余的空格會被移除或者說被忽略。

          段落文本其實也是HTML代碼的一部分,只不過它在p標簽內部,而例子2的空格是在兩個span標簽之間。


          理解了空格,現(xiàn)在看看空行,同理

          例子3:(文本內容中的空行)

          <p>這段文本中,輸入連續(xù)的空行
          
          
          
          
          
          大概輸入了五行。</p>

          顯示效果:如我們所見,文本代碼中的五行空行,顯示出來也只是一個空格。

          這段文本中,輸入連續(xù)的空行 大概輸入了五行。

          例子4:(元素之間/標簽之間的空行),只要把例子2中的空格換成空行就可以了,顯示效果和例子2的一樣,多行空行都只會顯示為一個空格。

          <span>span是一個行內標簽</span>
          
          
          
          
          
          <span>和前面的span元素之間隔了很多空行</span>


          span是一個行內標簽 和前面的span元素之間隔了很多空行

          得證:HTML 代碼中的所有連續(xù)的空格或空行(換行)都會被顯示為一個空格。


          既然如此,如果我們希望擴大兩個字符之間的間距,讓代碼中的連續(xù)空格或空行顯示出來的結果也是連續(xù)的空格或空行,那該怎么辦?其實很簡單。

          方法一:我們可以用預格式化標簽<pre>,無論是空格或空行都適用。

          <pre>
          這是
          預格式文本。
          它保留了      空格
          和換行。
          </pre>

          顯示效果

          這是
          預格式文本。
          它保留了      空格
          和換行。


          方法二:我們可以用空格實體符 代替空格,用換行標簽<br/>代替空行。雖然這種方法可以得到我們想要的顯示效果,但是對搜索引擎不是最友好的方式,因為 和<br/>在HTML中都是沒有語義的。所以建議盡量少用。另外需要注意的是, 必須小寫,而且最后面的分號是不能省略的。


          方法三:(適合空格)使用全角空格

          全角空格被解釋為漢字,所以不會被被解釋為HTML分隔符,可以按照實際的空格數(shù)顯示。

          問題:怎么使用全角輸入法?

          以搜狗輸入法為例,我們通常使用的是半角輸入,其狀態(tài)欄中有個月亮的標志,就說明正在使用的是半角輸入,如果是太陽的標志,就說明使用的是全角輸入。全角/半角的切換可以通過點擊標志,也可以通過快捷鍵 Shift+Space(空格符)切換。

          半角輸入(月亮)

          全角輸入(太陽)

          方法四:使用CSS樣式中字間隔屬性控制,CSS中的word-spacing 屬性可以改變字(單詞)之間的標準間隔。我們知道英文中兩個單詞之間是通過空格隔開的,所以我們視覺上可以這樣認為,word-spacing改變了(拉長或縮短)單詞之間那個空格的寬度。

          方法五:使用CSS樣式中的white-space 屬性,這個屬性聲明如何處理元素內的空白符。

          描述

          normal

          默認。空白會被瀏覽器忽略。

          pre

          空白會被瀏覽器保留。其行為方式類似 HTML 中的 <pre> 標簽。

          nowrap

          文本不會換行,文本會在在同一行上繼續(xù),直到遇到 <br> 標簽為止。

          pre-wrap

          保留空白符序列,但是正常地進行換行。

          pre-line

          合并空白符序列,但是保留換行符。


          white-space:normal;就是正常,和不設置一樣,連續(xù)空格和空行都只會顯示一個空格。

          white-space:nowrap;不換行是什么意思呢?正常情況下,當我們的文本超出了文本域,文本就會自動折行,這個設置就是說不自動折行了,而是碰到換行標簽<br />才換

          white-space:pre;和方法一相同,將文本原樣輸出顯示。當文本超出文本域時,不換行,會產(chǎn)生滾動條。

          white-space:pre-wrap;保留空格和空行,但當文本超出文本域時,會自動換行。

          white-space:pre-line;連續(xù)的空格會顯示為一個空格,但保留連續(xù)的空行。

          是why技術的第20篇原創(chuàng)文章

          本周本來是沒有時間寫技術文章的,為了周更不斷,想著去把之前發(fā)布在其他平臺的一篇原創(chuàng)文章搬過來就行。結果發(fā)現(xiàn),當年我寫的那篇文章,離真相還差著十萬八千里。

          而去搜索這個問題時,我的文章是檢索結果的第一個

          原文《http請求參數(shù)中加號被替換為空格及請求參數(shù)被URLDeCode的記錄》鏈接如下:

          https://www.jianshu.com/p/1a30b585c39e

          所以為了避免繼續(xù)誤導讀者,就算周末"爆肝",也得輸出此文,不得不發(fā)。

          這是我作為程序員的自我修養(yǎng)。

          加號變空格

          之前寫那篇文章的原因是碰到了兩個有趣的問題,如下

          首先,我們進行場景復現(xiàn),搭建項目的過程就不說了,用idea+springboot搭建一個簡單的web項目還不是信手拈來的事?

          正如上面的現(xiàn)象所示:我的入?yún)⑹?strong>jay+love,但是后臺接收到的是jay love,加號變空格了。為什么呢?

          源碼之下無秘密

          本文分析的Tomcat源碼版本為:9.0.29.

          通過Debug可以找到兩處關鍵的代碼:

          第一處:

          org.apache.tomcat.util.http.Parameters#processParameters(byte[], int, int, java.nio.charset.Charset) 下圖中的290行

          在這個地方因為有'+',所以把decodeValue參數(shù)設置為true,表示需要對請求中的value進行decode操作。

          decode的具體的源碼位置如下,也就是第二處關鍵代碼:

          org.apache.tomcat.util.buf.UDecoder#convert(org.apache.tomcat.util.buf.ByteChunk, boolean)


          可以看到,在源碼里面有一段代碼,是把'+'替換了為了空格,是特意做了這樣的特殊處理。

          整個方法的解讀如下:

          所以我的入?yún)⑹?strong>jay+love,但是后臺接收到的是jay love,加號變空格了。為什么呢?

          原因很簡單,在源碼中有一段代碼把'+'替換成了空格,刻意為之。

          為什么這樣做呢?

          之前的文章里面我寫的是:

          由于歷史原因,那到底是什么歷史原因呢?

          我在網(wǎng)上查了一圈,沒有找到具體的歷史原因,我看到的所有的關于這個問題的文章,要么只是給了解決方案,要么就是上面這一句歷史原因,一帶而過,含糊其辭。

          這里,我就明明白白的告訴你為啥。

          經(jīng)過我長時間的摸排,我找到了很多蛛絲馬跡,整理之后,我決定從JDK的一個"BUG"講起。

          對應鏈接:http://bugs.sun.com/view_bug.do?bug_id=4616184

          從提交時間上可以看出,該問題早在2001年,距今18年前就有人指出來了,并給JDK上報了BUG,他的描述如下:

          首先,我們先把他的測試代碼拿出來跑一下:

          他為什么說空格encode之后應該是%20呢?

          因為他在BUG里面提到了RFC2396標準。(RFC就不解釋了,你只要知道是業(yè)界認證的權威標準就行):

          http://www.ietf.org/rfc/rfc2396.txt

          在RFC2396的第2.4.1節(jié),明確的說了:"%20"是US-ASCII空格字符的轉義編碼。

          去查詢標準的ASCII碼你也可以發(fā)現(xiàn)確實是這樣的:

          用代碼實踐一下,證明以上結論:

          看java.net.URLEncoder#encode(java.lang.String, java.lang.String)的源碼也可以直觀的看到,源碼里面做了特殊處理

          再看java.net.URLDecoder#decode(java.lang.String, java.lang.String)的源碼:

          這里就和前面的呼應上了,這處理方式,一模一樣呀。所以為什么這樣處理,兩處地方屬于同宗同源啊!

          而提BUG的那個哥們?yōu)槭裁从X得這是一個BUG呢?

          雖然經(jīng)過試驗,'+'和'%20'經(jīng)過decode都能轉化為空格,但是他認為,根據(jù)RFC2396來講,這里只能是'%20',怎么能變成'+'呢?所以他覺得這是一個BUG。

          那我們看看JDK官方是怎么回復這個問題的呢?

          官方回復:

          這不是BUG啊,朋友!這個類就是遵循了HTML規(guī)范中的規(guī)定:如何對 HTML表單中的URLs進行encode。它不打算用于其他用途。


          而這樣做的原因,是因為包括HTML 4.01第17.13.4節(jié)和RFC 1866(已經(jīng)被W3C HTML推薦標準取代)都是這樣規(guī)定的。

          對于第一段話,官方的意思我理解是:這個類就是拿來對url進行encode的,不做其他用途。因為你調用了encode編碼,那就需要decode解碼,我只要保證你解碼之后的數(shù)據(jù)和你encode之前的數(shù)據(jù)是一樣的就行了。你要拿去搞其他事情,我就管不了了。

          而為什么這樣做呢?是因為規(guī)定就是這樣的呀,類似于國家標準就是這樣的,類似于產(chǎn)品經(jīng)理提出的需求就是這樣的呀。這里官方提出了兩個標準,一個是HTML 4.01,一個是RFC1866(這個已經(jīng)被其他的標準取代了,那我們就只看HTML 4.01)。

          HTML4.01是1999年12月24日發(fā)布的,在HTML4.0基礎上進行微小改進,W3C推薦標準 。


          在w3c上找到該標準,地址如下

          https://www.w3.org/TR/html401/interact/forms.html#h-17.13.4.1

          下圖圈起來的地方很關鍵,可以點開放大查看:

          找到HTML 4.01第17.13.4節(jié),其中明確指出:當content-type為application/x-www-form-urlencoded時,對names和vaules進行轉義,空格用'+'代替。

          HTML 4.01第17.13.4節(jié)原文如下:

          Control names and values are escaped. Space characters are replaced by `+'

          官方舉的雖然是HTML 4.01的例子,但是我翻譯了歷史文獻,發(fā)現(xiàn)其實在更早的HTML 3.2規(guī)范中就規(guī)定了,HTML 3.2規(guī)范在1996年就成為了W3C推薦標準,其中相關內容如下:

          鏈接地址:https://www.w3.org/TR/2018/SPSD-html32-20180315/

          而application/x-www-form-urlencoded是瀏覽器默認的content-type。

          在BUG里面提到的RFC2396標準是1998年8月提出來的

          HTML 3.2規(guī)范在1996年就成為了W3C推薦標準

          所以,我覺得這就是歷史原因!

          再說一次,在HTML 4.01規(guī)范中就明確規(guī)定了:當content-type為application/x-www-form-urlencoded時,對names和vaules進行轉義,空格用'+'代替。

          沒有原因,就是規(guī)定!我在查詢的過程中發(fā)現(xiàn),其他的編程語言也有這樣的問題,因為他們都遵從同樣的標準,就有了同樣的"歷史原因"。

          回到前面的這個地方:

          這里解碼的時候為什么把'+'轉化為空格呢?因為"歷史原因",如果URLs中出現(xiàn)了空格,需要用'+'替換,所以這里解碼的時候把'+'轉化回了空格。先有了編碼的操作,所以才會有解碼的操作。

          很多的文章都在說這是'+'的原因,甚至有的文章說'+'的編碼應該改為%20。但是其實上面分析過了,有問題的是空格,而不是'+'。

          那為什么我們在做表單提交的時候,也經(jīng)常寫'+'號呀,為什么沒有問題呢?

          因為當Html的表單被提交時, 每個表單域都會被Url編碼之后才在被發(fā)送,下面的小例子可以佐證:

          解決方案

          解決方案網(wǎng)上一大堆了,我這里羅列一下吧:

          方案一:修改客戶端,將客戶端帶'+'的參數(shù)中的'+'全部替換為?'%2B',如下:

          方案二:修改服務器端,將空格替換為'+',這種方式只適用于參數(shù)中'+'沒有空格的情況。如下:

          方案三:修改服務器端,將獲取參數(shù)的方法由?reuqest.?getParameter改為?request.getQueryString(),然后對得到的字符串進行解析。

          最后說一句

          正如我文章最開始說的,就算是熬夜爆肝,我也必須得輸出這篇文章,因為我最開始的文章不僅寫的表面,而且還有一些問題,我得對其進行糾正。

          讓我突然想起了之前和朋友的一次對話,他問我說:你作為程序員,時刻待命,只要系統(tǒng)一出問題你就立馬會響應。你不覺得累嗎?

          我回答道:說真的,當系統(tǒng)出問題,需要我排查問題的時候,我不覺得累。因為這個系統(tǒng)是我負責的,代碼是我自己一行行的寫出來的。出現(xiàn)了問題,我得證明我的系統(tǒng)是沒有問題的,是不是別人的打開方式不對。但是如果真的是我的代碼導致的問題,我會心有愧疚,我也得立即響應,對其負責。

          這是我作為一個程序員的自我修養(yǎng)。

          這篇文章的風格和《這道面試題我真不知道面試官想要的回答是什么》有點相似,全文描述的都是很小的知識點,甚至可以說是冷知識。一句話就能說出表面上的為什么,提煉出一個知識點。

          但是我覺得提煉出來的,是一個干癟癟的知識點,它不夠豐富,沒有探索的過程。

          而我所展示的是我去尋找這個問題的答案的過程。通過JDK的"BUG"把幾個協(xié)議串聯(lián)起來,而且是全世界共同遵循的協(xié)議,極具權威性。

          才疏學淺,難免會有紕漏,如果你發(fā)現(xiàn)了錯誤的地方,還請你留言給我指出來,我對其加以修改。

          感謝您的閱讀。

          以上。

          擊右上方紅色按鈕關注“小鄭搞碼事”,每天都能學到知識,搞懂一個問題!

          由于HTML代碼的空格通常會被瀏覽器忽略,所以我們很有必要對瀏覽器處理空格的一些規(guī)則有個詳細的認識,這樣我們后面才能詳述它的解決辦法。

          一、默認規(guī)則

          效果是這樣的:

          由此可此可以知道瀏覽器的默認處理規(guī)則一:文字的前后空格都會忽略,內部連續(xù)空格只有自作一個。

          原樣輸出可能是我們這樣寫代碼的本意,要讓這段代碼原樣輸出的方法有兩個(使用標簽/使用表示空格的實體代碼):

          方法一:<pre><span class="space"> 小鄭 搞碼 </span></pre>

          方法二:<span class="space"> 小鄭 搞碼 </span>

          二、另一個規(guī)則

          關于規(guī)則部分還有一點,來看一段代碼:

          效果是:

          表示,瀏覽器對字符的處理不僅限于空格,還有制表符(\t),換行符(\r和\n)。

          同樣讓這段代碼換行可能是我們寫的本意,讓這段代碼換行的方法有兩個:

          方法一:套一個pre標簽

          方法二:<span class="space">小鄭<br/>搞碼</span>

          最后總結一下:

          HTML語言的空格處理,基本上就是直接過濾。這樣的處理過于粗糙,完全忽視了原始文本內部的空格可能是有意義的。所以CSS提供了一個屬性white-space屬性來靈活控制空格。下篇詳述。


          主站蜘蛛池模板: 久久国产精品亚洲一区二区| 亚洲AV日韩综合一区尤物| 亚洲一区精品伊人久久伊人| 一区二区三区美女视频| 亚洲性日韩精品一区二区三区 | 亚洲精品无码一区二区| 无码精品不卡一区二区三区| 日本精品一区二区三本中文 | 岛国精品一区免费视频在线观看 | 亚洲视频一区调教| 精产国品一区二区三产区| 一区二区在线播放视频| 无码人妻一区二区三区在线视频 | 国产在线乱子伦一区二区| 国产成人一区二区在线不卡| 国产一区在线视频| 亚洲国产AV一区二区三区四区 | 精品一区二区久久久久久久网站| 无码精品人妻一区二区三区免费看 | 国产a久久精品一区二区三区| 成人一区二区免费视频| 国产美女在线一区二区三区| 日本一区二区三区四区视频| 国产一区二区中文字幕| 午夜性色一区二区三区不卡视频| 正在播放国产一区| 精品福利一区二区三| 国产伦理一区二区三区| 麻豆aⅴ精品无码一区二区| 麻豆精品一区二区综合av| 精品一区二区三区在线观看l| 中文字幕日韩一区二区不卡| 国模私拍福利一区二区| 无码人妻久久一区二区三区免费丨 | 亚洲高清美女一区二区三区| 日韩一区二区视频在线观看| 韩国精品福利一区二区三区| 精品国产AⅤ一区二区三区4区 | 国产情侣一区二区| 国模精品一区二区三区视频 | 日韩人妻一区二区三区免费|