2010-05-14 85 views
3

讓我們假設一個用戶輸入一些資源的地址,我們需要把它翻譯成:IDN感知工具來編碼/解碼人類可讀IRI /從有效的URI

<a href="valid URI here">human readable form</a> 

HTML4規範是指RFC 3986只允許主機部分中的ASCII字母數字字符和短劃線以及其他部分中的所有非ASCII字符應採用百分比編碼。這就是我想要在href屬性中使鏈接在所有瀏覽器中正常工作的原因。 IDN應使用Punycode進行編碼。

HTML5草案指的是RFC 3987,它還允許主機部分中的百分比編碼的unicode字符和主機部分和其他部分中的大部分unicode字符,而不對它們進行編碼。用戶可以以任何這些形式輸入地址。爲了提供可讀的形式,我需要解碼所有可打印的字符。請注意,地址的某些部分可能不符合有效的UTF-8序列,通常在目標站點使用其他字符編碼時。

我想獲得什麼樣的一個例子:

<a href="http://xn--80aswg.xn--p1ai/%D0%BF%D1%83%D1%82%D1%8C?%D0%B7%D0%B0%D0%BF%D1%80%D0%BE%D1%81"> 
http://сайт.рф/путь?запрос</a> 

是否有解決這些任務的任何工具?我特別感興趣的是Python和JavaScript庫。

更新:我知道有一種方法可以在Python和JavaScript中執行百分比和Punycode(沒有適當的規範化,但我可以忍受它)編碼/解碼。整個任務需要更多的工作,並且存在一些陷阱(一些字符應該總是被編碼或從不被編碼,這取決於上下文)。我想知道是否有準備使用庫的整個的問題,因爲它似乎是相當普遍的,現代瀏覽器已經做了這樣的轉換(嘗試在Google Chrome中輸入http://%D1%81%D0%B0%D0%B9%D1%82.%D1%80%D1%84/,它將替換爲http://сайт.рф/,但在HTTP中使用Host: xn--80aswg.xn--p1ai請求)。

Update2:Vinay Sajip指出,Werkzeug具有iri_to_uri和uri_to_iri函數,可以正確處理大多數情況。到目前爲止,我發現只有兩種情況失敗:編碼百分比的主機(很容易修復)和無效的utf-8序列(要做得很好,這有點棘手,但不應該是一個問題)。

我仍然在JavaScript中尋找圖書館。這不難寫,但我寧願避免發明輪子。

+0

我在一個Javascript實現的答案中添加了一個鏈接,該鏈接可能適合您的需求。這是公共領域,但需要單元測試,我會說。 – 2010-05-15 16:07:51

+0

Duplicate:http://stackoverflow.com/questions/183485/can-anyone-recommend-a-good-free-javascript-for-punycode-to-unicode-conversion – 2010-05-14 10:13:48

+0

感謝您的鏈接。問題不在於Punycode編碼實現(很簡單),而是一個更大的問題。 – 2010-05-14 11:46:59

回答

2

如果我理解正確的話,那麼你可以使用包含在Python電池:

# -*- coding: utf-8 -*- 

import urllib 
import urlparse 

URL1 = u'http://сайт.рф/путь?запрос' 
URL2 = 'http://%D1%81%D0%B0%D0%B9%D1%82.%D1%80%D1%84/' 

def to_idn(url): 
    parts = list(urlparse.urlparse(url)) 
    parts[1] = parts[1].encode('idna') 
    parts[2:] = [urllib.quote(s.encode('utf-8')) for s in parts[2:]] 
    return urlparse.urlunparse(parts) 

def from_idn(url): 
    return urllib.unquote(url) 

print to_idn(URL1) 
print from_idn(URL2) 
print to_idn(from_idn(URL2).decode('utf-8')) 

它打印

http://xn--80aswg.xn--p1ai/%D0%BF%D1%83%D1%82%D1%8C?%D0%B7%D0%B0%D0%BF%D1%80%D0%BE%D1%81 
http://сайт.рф/ 
http://xn--80aswg.xn--p1ai/ 

,它看起來像你想要什麼。我不確定你的意思是什麼特殊情況 - 也許你可以舉一些你所指的陷阱的例子嗎?

更新:我只記得,WERKZEUG在0.6及更高版本(鏈接到文檔的相關部分)版本iri_to_uriuri_to_iri功能。

更多更新:對不起,我沒有注意到你正在尋找一個JavaScript實現以及Python實現。 punycode的現有公共領域Javascript實現是here。不過,我不能擔保。當然,您也可以使用內置的JavaScript API。

+0

您的功能僅適用於此示例。 Werkzeug功能適用於大多數情況,可以輕鬆修復其他情況,謝謝! – 2010-05-14 16:55:54

+0

您的編碼行有 - *'而不是 - * - 。爲了避免這種混亂,你可以寫下 #coding:utf-8 – temoto 2010-05-14 17:23:26