今天作網站【標籤】篩選功能時,出現了這麼個奇葩的問題。
我是直接經過<a>標籤中href來跳轉的,url中包含漢字
<a href="/tags/標籤A">標籤A</a>
後臺代碼是這樣的:html
@RequestMapping(value = "/tags/{tagname}") public String tags(@PathVariable String tagname) {
// ISO-8859-1 ==> UTF-8 進行編碼轉換
tagname = encode_to_utf8(tagname);
// 其他處理略
}
按理說這樣就好了,各大瀏覽器也正常執行了。前端
可是,一不下心發現,只要URL中出現「充」這個漢字,直接就報404錯誤java
例如這樣:後端
<a href="/tags/標籤充A">標籤充A</a>
奇葩吧。瀏覽器
通過漫長的調查發現,緣由有可能是:app
充這個漢字在URL中直接提交,通過瀏覽器轉碼後,會變成一串包含「/」的「亂碼」。測試
後來通過相似測試發現,果真只要URL中包含「/」的參數,都沒法經過@PathVariable正確匹配。網站
有人說不如改爲這樣:編碼
方案1:url
在Server端經過urlencode把漢字先進行UTF-8編碼,而後扔到前端。
否決:這樣作的話,URL就會變成這個醜樣,這和亂碼有什麼區別?真心不喜歡。
<a href="/tags/%D6%D0%B9%FA">標籤充A</a>
後來縱觀各大站點,各有各的作法
方案2:
<a href="/tags?tagname=標籤充A">標籤充A</a>
而後在Controller中用@RequestParam來接收參數,這樣確實是能夠的。
否決:可是SEO大神說,url中包含?的動態參數後,有可能會被蜘蛛重複抓取,不利於SEO。
方案3 :把漢字便籤轉換成拼音
<a href="/tags/biaoqianchongA">標籤充A</a>
否決:這樣能夠是能夠,可是還要在搞一個漢字轉拼音插件,並且看上去也不直觀,很差。
方案4:給標籤一個ID
<a href="/tags/T1">標籤充A</a>
否決:這樣能夠是能夠,可是我還要該表結構,蛋疼。
方案5:用JS阻斷A的href,實現POST跳轉
否決:如今百度已經能夠解析JS了嗎?
你們還有別的方案沒有??
難道就沒有辦法在保持URL格式與漢字都不變的狀況,實現這個功能嗎?
最後終於發現,有人這樣搞定了!
前端:
<a href="/tags/標籤充A">標籤充A</a>
後端:
@RequestMapping(value = "/tags/**") public String tags(HttpServletRequest request) { // ISO-8859-1 ==> UTF-8 進行編碼轉換 String tagname = extractPathFromPattern(request); tagname = ToolUtils.encodeStr(tagname); // 其他處理略 } // 把指定URL後的字符串所有截斷當成參數 // 這麼作是爲了防止URL中包含中文或者特殊字符(/等)時,匹配不了的問題 private static String extractPathFromPattern( final HttpServletRequest request) { String path = (String) request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE); String bestMatchPattern = (String) request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE); return new AntPathMatcher().extractPathWithinPattern(bestMatchPattern, path); }
搞完以後,無論你輸入什麼樣的URL,都能進入到指定的方法!
<a href="/tags/標籤充A">標籤充A</a>
<a href="/tags/標籤充A/asd/asd">標籤充A</a>
<a href="/tags/標籤充A/BB/cc.html">標籤充A</a>參考原文地址:http://kamatama41.hatenablog.com/entry/20130411/1365668200