統一資源定位系統(uniform resource locator;URL)是因特網的 萬維網服務 程序上用于指定信息位置的表示方法。它最初是由蒂姆·伯納斯·李發明用來作為萬維網的地址。現在它已經被 萬維網聯盟 編制為 互聯網標準 RFC1738。
基本介紹
因特網上的可用資源可以用簡單字符串來表示,該文檔就是描述了這種字符串的語法和語義。而這些字符串則被稱為:“統一資源定位器”(URL)。這篇說明源于萬維網全球信息主動組織(World Wide Web global informationinitiative)介紹的概念。RFC1630《通用資源標志符》描述了一些對象數據,他們自1990年起就開始使用這些對象數據。這篇URL說明符合《因特網資源定位符的功能需求(Functional Requirements for Internet Resource Locators》中說明的需求。這篇文檔是由工程任務組織(IETF)的URI工作小組寫的。
URL語法
正如訪問資源的方法有很多種一樣,對資源進行定位的方案也有好幾種。URL的一般語法只是為使用協議來建立新方案提供了一個框架,當然除了已經在這篇文檔中定義過的。URL通過提供資源位置的一種抽象標志符來對資源進行定位。系統定位了一個資源后,可能會對它進行各種各樣的操作,這些操作可以抽象為下面的幾個詞:訪問,更新,替換,發現屬性。一般來說,只有訪問方法這一項在任何URL方案中都需要進行描述。
主要部分
第五部分給出了URL語法的完整BNF描述。
URL通常被寫成如下形式:<方案>:<方案描述部分>
一個URL包含了它使用的方案名稱(<方案>),其后緊跟一個 冒號 ,然后是一個字符串(<方案描述部分>),這部分的解釋由所使用的方案來決定。方案名稱由一串字符組成。小寫字母“a”——“z”,數字,字符加號(“+”),句點(“.”)和連字號(“-”)都可以。為了方便起見,程序在解釋URL的時候應該視方案名稱中的大寫字母和小寫字母一樣。(例如:視“HTTP”和“http”一樣)。
字符編碼
URL是由一串字符組成,這些字符可以是字母,數字和 特殊符號 。一個URL可以用多種方法來表現,例如:紙上的字跡,或者是用字符集編碼的 八位字節 序列。URL的解釋僅取決于所用字符的特性。在大多數URL方案中,都是使用URL不同部分的字符序列來代表因特網協議中所使用的八位字節序列。例如,在ftp方案中主機名,目錄名和文件名就是這樣的八位字節序列,它們用URL的不同部分代表。在這些部分里,一個八位字節數可以用這樣的字符來表示:該字符在US—ASCII[20]編碼字符集中的編碼是這個八位字節數。另外,八位字節數可以被編成如下形式的代碼:“%”后加兩個十六進制數字(來自于“0123456789ABCDEF”),這兩個十六進制數字代表了這八位字節數的值。(字符“abcdef”也可以用于十六進制編碼)。如果存在下面的情況:八位字節數在US-ASCII字符集中沒有相應的可顯示字符,或者使用相應字符會產生不安全因素,或者相應的字符被保留用于特定的URL方案的解釋,那么它們必須被編成代碼。
• 沒有相應的可顯示字符:URL只能用US-ASCII字符編碼集中的可顯示字符表示。US-ASCII中沒有用到十六進制的八位字節80-FF,并且00-1F和7F代表了控制字符,這些字符必須進行編碼。
• 不安全:字符不安全的原因很多。空格字符就是不安全的,因為URL在被轉錄或者被排版或者被字處理程序處理后其中重要的空格可能被忽略,而可忽略的空格卻有可能被解釋了。“<”和“>”字符也是不安全的,因為它們被用來作為URL在文本中的分隔符;而在有些系統中用引號“"”來界定URL。“#”字符也是不安全的,因為它在萬維網和其他一些系統中被用來從“片段/ 錨點 ”標志符中界定URL,所以它通常都要被編碼。字符“%”被用來對其他字符進行編碼,它也是不安全的。其他一些字符,如:"{","}","|","\","^","~","[","]",和"`",由于網關和其他傳輸代理有時會對這些字符進行修改,所以它們也是不安全的。必須對URL中所有不安全的字符進行編碼。例如,URL中的字符“#”即使是在通常不處理片斷或者錨點標志符的系統也需要進行編碼,這樣如果這個URL被拷貝到使用這些標志符的系統中,也不必改變URL編碼了。
• 保留:許多URL方案保留了一些字符并賦予特定的含義:它們出現在URL的特定部位并表示特定的含義。如果一個字符對應的八位字節在方案中被保留了,那么這個八位字節必須進行編碼。字符";","/","?",":","@","="和"&"可能被某個方案所保留,除此之外沒有其他的保留字符。通常情況下一個八位字節被用一個字符表示后或者被編碼之后,URL的解釋都是一樣的。但這對于保留字符來說就不適用了:對某一特定方案的保留字符進行編碼可能會改變URL的語義。這樣,在URL中只有字母與數字,以及 特殊字符 “$-_.+!*'(),”和用作保留目的的保留字符可以不進行編碼。另一方面,不必進行編碼的字符(包括字母與數字)如果出現在URL的特定部位,只要它們不用作保留目的,則可進行編碼。
方案和關系
URL有時候被用來定位那些包含指示器的資源,而這些指示器又指向其他資源。有時候這些指示器用 關系鏈接 表示,在關系鏈接中第二資源的位置表示符原則上“和那些除了帶有次相關路徑的表示符相同”。在這篇文檔中沒有對關系鏈接進行描述。但是,關系鏈接的使用依賴于包含分層結構的原始URL,它是關系鏈接的基礎。有些URL方案(例如ftp,http,和文件方案)包含的名字可以被認為是分層次的;這些層次之間用“/”分隔。
特殊方案
一些已經存在的標準協議和正處于試驗中的協議之間的映射關系的輪廓用BNF語法定義進行描述。下面對一些協議進行了注釋:
ftp File Transfer protocol(文件傳輸協議)
http Hypertext Transfer Protocol (超文本傳輸協議)
gopher The Gopher protocol(Gopher協議)
mailto Electronic mail address( 電子郵件地址 )
news USENET news(USENET新聞)
nntp USENET news using NNTP access(使用NNTP訪問的USENET新聞)
telnet Reference to interactive sessions(交互式會話訪問)
wais Wide Area Information Servers( 廣域信息服務系統 )
file Host-specific file names(特殊主機文件名)
prospero Prospero Directory Service(prospero目錄服務)
在以后的說明書中可能會對其他一些方案加以描述。這篇文檔的第四部分介紹了如何注冊新的方案,并且列出了一些正在研究中的方案名。
通用方案語法
雖然URL其他部分的語法因方案的不同而不同,但那些直接使用基于IP的協議來定位因特網上的主機的URL方案都使用了如下形式的通用語法來表示特定的方案數據:
//<用戶名>:<密碼>@<主機>:<端口>/
可能會省略“<用戶名>:<密碼>@”,“:<密碼>”,“:<端口>”,和“/
• 用戶名:任意的用戶名稱。有些方案(例如:ftp)允許使用用戶名稱的描述。
• 密碼:任意的密碼。如果存在的話,它緊跟在用戶名后面并用一個冒號隔開。
用戶名(和密碼)如果存在的話,其后緊跟一個商用符號“@”。在用戶名和密碼字段中出現的任何“:”,“@”或者“/”都要進行編碼。注意空的用戶名或者密碼不同于沒有用戶名和密碼;決不能在沒有指定用戶名的情況下指定密碼。例如:
• 主機:網絡主機的域名,或者它的以“.”分隔的四組十進制數字集合形式的IP地址。域名的形式在RFC1034[13]的3.5節和RFC1123[5]的2.1節中進行了描述,即用“.”分隔的域標志串,域標志以字母或者數字開頭和結束,也可能包含“-”字符。最右邊的域標志不能以數字開頭,這樣就在語法結構上將域名和IP地址區分開來了。
• 端口:指明鏈接的端口。大部分方案都給協議指定一個默認的端口。也可以隨意指定一個十進制形式的端口,并用冒號與主機隔開。如果忽略端口,那么這個冒號也要忽略。
• url路徑:定位符的其他部分由方案的特殊數據組成,這些特殊數據被稱為“url-路徑”。它提供了如何對特定資源進行訪問的詳細信息。注意主機(或端口)與url-路徑間的“/”不是url-路徑的一部分。url-路徑的語法依賴于所使用的方案。也依賴于它在方案中的解釋方法。
FTP
FTPURL方案可以用來指定因特網上使用FTP協議(RFC959)的可達主機上的文件和目錄。FTPURL遵從3.1節所描述的語法。如果:<端口>被省略的話,則使用缺省端口21。
1、FTP用戶名和密碼
在連接上FTP服務器后,可以用“USER”和“PASS”命令來指定用戶名和密碼。如果沒有提供用戶名或者密碼并且FTP服務器只要求一項,那么將使用到“匿名”服務器的轉換,如下所示:用戶名“anonymous”被發送。訪問資源的終端用戶的因特網電子郵件地址被作為密碼發送。如果URL提供用戶名但不提供密碼,那么遠程服務器將要求提供密碼,而解釋FTPURL的程序則要求用戶輸入密碼。
2、FTPURL-路徑FTPURL的URL-路徑語法如下:
這里的
3、FTP類型編碼是可選擇的
FTPURL的整個;type=
4、層次
在有些文件系統中,用來表示URL的層次結構的“/”與用來構建文件系統層次的分隔符相同,這樣一來,文件名和URL路徑看起來就很像。但這并不意味著URL是一個Unix文件名。
5、優化
客戶端通過FTP對資源進行訪問時可能會使用一些額外的搜索方法來優化交互過程。例如,對一些FTP服務器來說,當訪問同一個服務器的多個URL的時候,則保持控制連接一直打開是比較合理的。但FTP協議沒有通用的層次模式,因此當一個改變目錄的命令發出后,如果是一個不同的路徑,那么一般不可能推斷出下一次將要給另一個目錄發送什么樣的序列。唯一可靠的算法是斷開然后重新建立控制連接。
HTTP
HTTPURL方案是用來標志因特網上使用HTTP(HyperTextTransferProtocol,超文本傳輸協議)的可達資源。HTTP協議在其他的地方進行了詳細說明。本文只介紹了HTTPURL的語法。HTTPURL的形式如下:
http://
其中
GOPHER
GopherURL方案用來標志因特網上使用Gopher協議的可達資源。基本Gopher協議是在RFC1436中介紹的,它支持項和項(目錄)集合。Gopher+協議則在基本Gopher協議的基礎上進行了擴展,并且 向上兼容 。中對它進行了介紹。Gopher+支持聯合屬性的任意集合和使用Gopher項的替換數據表示。GopherURL提供了Gopher與Gopher+的項和項屬性。
1、GopherURL語法
GopherURL的形式如下:
gopher://
這里的
如果:
2、為Gopher搜索引擎指定URL
如果URL被提交到Gopher搜索引擎進行查詢,那么選擇器后將緊跟一個已編碼的tab(%09)和一個搜索字符串。Gopher客戶為了向Gopher搜索服務器提交一個搜索必須向Gopher服務器發送
3、Gopher+項的URL語法
Gopher+項的URL有一個已編碼的tab字符(%09)和一個Gopher+字符串。注意盡管
4、缺省的Gopher+數據表示
當一個Gopher服務器向客戶返回目錄列表時,Gopher+項后面跟著一個“+”(表示Gopher+項)或者一個“?”(表示具有與它們相關聯的+ASK形式的Gopher+項)。Gopher+字符串只有一個字符“+”的GopherURL采用項的缺省的視圖(數據表示),而Gopher+字符串只有一個字符“?”的GopherURL則采用具有相關聯的Gopher電子表格的項。
5、具有電子表格的Gopher+項
具有與之相關聯的+ASK的Gopher+項(也就是跟著一個“?”的Gopher+項)要求客戶端取得該項的+ASK屬性來獲得表格定義,然后讓用戶填寫這個表格并將用戶應答和獲得項的選擇器字符串一起返回。Gopher+客戶端知道如何完成這些工作,但需要依賴于Gopher+項描述中的“?”標簽來知道什么時候處理這種情況。Gopher+項中的“?”被用來與Gopher+協議中這種符號的用法相兼容。
6、Gopher+項屬性集
為了表示項的Gopher+屬性,GopherURL的Gopher+字符串由“!”或者“$”組成。“!”涉及Gopher+項的所有屬性。“$”則涉及Gopher目錄中所有項的所有項屬性。
7、涉及特定的Gopher+屬性
為了表示特殊的屬性,URL的gopher+_string是“!
8、Gopher+交替視圖的URL語法
Gopher+允許項有優化的交替數據表示(交替視圖)。Gopher+客戶端發送適當的視圖和語言標志(出現在項的+VIEW屬性里)來獲得Gopher+的交替視圖。為了引用一個特定的Gopher+交替視圖試圖,URL的Gopher+字符串的形式必須如下所示:
+<視圖名稱>%20<語言名稱>
例如,Gopher+字符串"+application/postscript%20Es_ES"引用了一個Gopher+項的交替視圖的西班牙語附注。
9、Gopher+電子表格的URL語法
一個引用了填充有特定數據的Gopher+電子表格(一個ASK塊)所參考的項的URL的Gopher+字符串是通過對客戶送給服務器的gopher+字符串進行編碼得到的。這個gopher+字符串的形式如下所示:
+%091%0D%0A+-1%0D%0A
Gopher客戶端為了獲得這個項,它發送如下信息給Gopher服務器:
MAILTO
mailtoURL方案是用來指明一個個體或者服務的因特網郵件地址的。它只代表因特網郵件地址,而不表示任何其它的附加信息。 Mailto URL的形式如下所示:
mailto:< rfc 822-addr-spec>
這里的
NEWS
新聞URL方案被用來查閱新聞組或者USENET新聞上的獨立文章,這一點在RFC1036中詳細說明了。新聞URL的形式是下面兩個之一:
news:< newsgroup -name>
news:
是一個用句點分隔的層次名稱,例如:“comp.infosystems.www.misc”。
NNTP
(NetworkNewsTransferProtocol, 網絡新聞傳輸協議 )URL方案是引用新聞文章的另一個方法,這個方案在用來從NNTP服務器指定新聞文章時是非常有用的(RFC977)。網絡新聞傳輸協議URL的形式如下:
nntp://
這里的
TELNET
遠程登錄 URL方案被用來指明交互式服務,這種服務可以通過Telnet協議來進行訪問。telnetURL的形式如下:
telnet://
向3.1節所講的那樣,最后面的“/”字符可以被省略。如果:
WAIS
(WideAreaInformationServers,廣域信息服務系統)WAISURL方案用來指示WAIS數據庫,搜索或者WAIS數據庫中可用的單個文檔。WAIS在中進行了描述。RFC1625[17]對WAIS協議進行了闡述。雖然WAIS協議是基于Z39.50-1988的,但WAISURL方案并不是特意用來和任意的Z39.50服務一起使用的。WAISURL有如下幾個形式:
wais://
wais://
wais://
這里的
FILES
文件URL方案被用來指定那些特定主機上的可訪問的文件。這個方案和其它大多數方案不一樣,因為它并不表示一個在因特網上普遍可訪問的資源。文件URL的形式如下:
file://
這里的
有一種特殊情況,就是
文件URL方案是與眾不同的,因為它不指定一個因特網協議或者訪問這些文件的方法;這樣它在主機間網絡協議上的效用是有限的。
PROSPERO
ProsperoURL方案是用來指定那些可以通過Prospero目錄服務訪問的資源。Prospero協議在其它地方介紹了。ProsperoURL的形式如下:
prospero://
這里
新方案注冊
可以通過定義一個到相應URL語法的映射和使用一個新的前綴來引入一個新的方案。URL試驗方案可以通過團體間的共同協議來使用。用字符“x-”開頭的方案名稱是保留給試驗方案用的。國際數字分配權威(IANA,InternetAssignedNumbersAuthority)將管理URL方案的注冊。任何提交的新URL方案都必須包含一個訪問該方案中資源的法則的定義還必須包含描述這個方案的語法。URL方案必須具有可論證的實用性和可操作性。提供這樣一個示范的方法就是借助一個為使用已有協議的客戶端提供新方案中的對象的 網關 。如果新方案不能夠定位一個數據對象資源,那么這個新領域中的名稱的屬性必須要進行清晰的定義。新方案應該在適當的地方努力遵從與已有方案相同的語法規則。對于可以用URL訪問的協議的地方也是同樣的。客戶端軟件被規定配置成使用特定網關定位符來通過新的命名方案間接訪問。下面的方案已經多次被提議,但這個文檔沒有定義它自己的語法。它建議IANA保留它們的方案名以備將來定義:
afs Andrew文件系統 全局文件名(Andrew FileSystem globalfilenames)。
mid電子郵件報文標志(Message identifiers forelectronicmail).
cidMIME主體部分的內容標志符(ContentidentifiersforMIMEbody
parts).
nfs 網絡文件系統 (NFS)文件名(NetworkFileSystemfilenames).
tn3270交互式3270競爭會話(Interactive3270emulationsessions).
mailserver訪問郵件服務器上的有效數據(Accesstodataavailablefrommail
servers).
z39.50訪問ANSIZ39.50服務(AccesstoANSIZ39.50services).
BNF
這是統一資源定位器語法的類BNF描述,它使用了RFC822中的約定,除了用“|”表示
選擇,用方括號[]將可選或者重復的元素括起來之外。簡單地說就是文字用引號""引起
來,可選元素放在方括號[]內,元素可以用
缺省為0。
;URL的一般形式如下:
genericurl=scheme":"schemepart
;特定的預定義方案在這里進行定義;新方案可以在IANA那兒注冊
url=httpurl|ftpurl|newsurl|
nntpurl|telneturl|gopherurl|
waisurl|mailtourl|fileurl|
prosperourl|otherurl
;新方案遵從一般語法
otherurl=genericurl
;方案都是小寫的;解釋程序應該忽略大小寫
scheme=1*[lowalpha|digit|"+"|"-"|"."]
schemepart=*xchar|ip-schemepart
;基于協議的ip的URL方案部分:
ip-schemepart="//"login["/"urlpath]
login=[user[":"password]"@"]hostport
hostport=host[":"port]
host= hostname |hostnumber
hostname=*[domainlabel"."]toplabel
domainlabel=alphadigit|alphadigit*[alphadigit|"-"]alphadigit
toplabel=alpha|alpha*[alphadigit|"-"]alphadigit
alphadigit=alpha|digit
hostnumber=digits"."digits"."digits"."digits
port=digits
user=*[uchar|";"|"?"|"&"|"="]
password=*[uchar|";"|"?"|"&"|"="]
urlpath=*xchar;建立在3.1節的協議基礎上
;預定義方案:
;FTP(文件傳輸協議,請參考RFC959)
ftpurl="ftp://"login["/"fpath[";type="ftptype]]
fpath=fsegment*["/"fsegment]
fsegment=*[uchar|"?"|":"|"@"|"&"|"="]
ftptype="A"|"I"|"D"|"a"|"i"|"d"
;FILE(文件)
fileurl="file://"[host|"localhost"]"/"fpath
;HTTP(超文本傳輸協議)
httpurl="http://"hostport["/"hpath["?"search]]
hpath=hsegment*["/"hsegment]
hsegment=*[uchar|";"|":"|"@"|"&"|"="]
search=*[uchar|";"|":"|"@"|"&"|"="]
;GOPHER(請參考RFC1436)
gopherurl="gopher://"hostport[/[gtype[selector
["%09"search["%09"gopher+_string]]]]]
gtype=xchar
selector=*xchar
gopher+_string=*xchar
;MAILTO(請參考RFC822)
mailtourl="mailto:"encoded822addr
encoded822addr=1*xchar;在RFC822中進一步定義了
;NEWS(新聞,請參考RFC1036)
newsurl="news:"grouppart
grouppart="*"|group|article
group=alpha*[alpha|digit|"-"|"."|"+"|"_"]
article=1*[uchar|";"|"/"|"?"|":"|"&"|"="]"@"host
;NNTP(網絡新聞傳輸協議,請參考RFC977)
nntpurl="nntp://"hostport"/"group["/"digits]
;TELNET(遠程登錄協議)
telneturl="telnet://"login["/"]
;WAIS(廣域信息服務系統,請參考RFC1625)
waisurl=waisdatabase|waisindex|waisdoc
waisdatabase="wais://"hostport"/"database
waisindex="wais://"hostport"/"database"?"search
waisdoc="wais://"hostport"/"database"/"wtype"/"wpath
database=*uchar
wtype=*uchar
wpath=*uchar
;PROSPERO
prosperourl="prospero://"hostport"/"ppath*[fieldspec]
ppath=psegment*["/"psegment]
psegment=*[uchar|"?"|":"|"@"|"&"|"="]
fieldspec=";"fieldname"="fieldvalue
fieldname=*[uchar|"?"|":"|"@"|"&"]
fieldvalue=*[uchar|"?"|":"|"@"|"&"]
其他的定義
lowalpha="a"|"b"|"c"|"d"|"e"|"f"|"g"|"h"|
"i"|"j"|"k"|"l"|"m"|"n"|"o"|"p"|
"q"|"r"|"s"|"t"|"u"|"v"|"w"|"x"|
"y"|"z"
hialpha="A"|"B"|"C"|"D"|"E"|"F"|"G"|"H"|"I"|
"J"|"K"|"L"|"M"|"N"|"O"|"P"|"Q"|"R"|
"S"|"T"|"U"|"V"|"W"|"X"|"Y"|"Z"
alpha=lowalpha|hialpha
digit="0"|"1"|"2"|"3"|"4"|"5"|"6"|"7"|
"8"|"9"
safe="$"|"-"|"_"|"."|"+"
extra="!"|"*"|"'"|"("|")"|","
national="{"|"}"|"|"|"\"|"^"|"~"|"["|"]"|"`"
punctuation="<"|">"|"#"|"%"|<">
reserved=";"|"/"|"?"|":"|"@"|"&"|"="
hex=digit|"A"|"B"|"C"|"D"|"E"|"F"|
"a"|"b"|"c"|"d"|"e"|"f"
escape="%"hexhex
unreserved=alpha|digit|safe|extra
uchar=unreserved|escape
xchar=unreserved|reserved|escape
digits=1*digit
安全事項
URL方案自身并不會造成安全威脅。用戶需要小心的是:在一個時刻指向一個給定對象的URL并不會保證一直指向這個對象。甚至也不保證因服務器上對象的移動而會在后來指向另一個不同的對象。一種同URL相關的安全威脅是:構建一個試圖執行像取回對象這樣無害的等冪操作的URL有時可能會導致發生破壞性的遠程操作。這個不安全的URL通常是通過指定一個除了那些保留給正在討論的網絡協議用的端口數產生的。客戶端在無意間同一個服務器打了交道,而這個服務器實際上正在運行一個不同的協議,這樣就導致URL內容中包含的指令被其他的協議解釋了,從而產生意外操作。一個例子就是使用gopherURL來生成一個原始的消息并通過SMTP服務器來發送。在使用那些指定端口不是缺省端口的URL時應該進行警告,尤其是在這個端口數出現在保留空間里面的情況下。當URL包含有嵌入式已編碼的特定協議中的分隔符(例如,telnet協議的CR和LF字符)并且在傳輸前沒有被解碼時應該引起注意。這樣除了可能被用來模擬一個超出其范圍的操作或者參數,會干擾這個協議,并再一次引起執行意想不到的而且可能是有害的遠程操作。使用包含應該作為秘密的密碼的URL是非常輕率的。