第一章 發(fā)送HTTP請(qǐng)求

第一章 發(fā)送HTTP請(qǐng)求

本主題介紹如何發(fā)送HTTP請(qǐng)求(如POSTGET)和處理響應(yīng)。

HTTP請(qǐng)求簡(jiǎn)介

可以創(chuàng)建%Net.HttpRequest的實(shí)例來(lái)發(fā)送各種HTTP請(qǐng)求并接收響應(yīng)避除。此對(duì)象相當(dāng)于Web瀏覽器呵燕,可以使用它發(fā)出多個(gè)請(qǐng)求凌盯。它會(huì)自動(dòng)發(fā)送正確的cookie,并根據(jù)需要設(shè)置Referer標(biāo)頭。

要?jiǎng)?chuàng)建HTTP請(qǐng)求少欺,請(qǐng)使用以下常規(guī)流程:

  1. 創(chuàng)建%Net.HttpRequest的實(shí)例白翻。
  2. 設(shè)置此實(shí)例的屬性以指示要與之通信的Web服務(wù)器乍炉。基本屬性如下:
  • 服務(wù)器指定Web服務(wù)器的IP地址或計(jì)算機(jī)名稱滤馍。默認(rèn)值為localhost岛琼。

注意:不要將http://https://作為服務(wù)器值的一部分。這將導(dǎo)致錯(cuò)誤#6059:無(wú)法打開到服務(wù)器http:/的TCP/IP套接字巢株。

  1. 可以選擇設(shè)置HTTP請(qǐng)求的其他屬性和調(diào)用方法槐瑞,如指定其他HTTP請(qǐng)求屬性中所述。
  2. 然后阁苞,通過(guò)調(diào)用%Net.HttpRequest實(shí)例的get()方法或其他方法來(lái)發(fā)送HTTP請(qǐng)求困檩,如“發(fā)送HTTP請(qǐng)求”中所述。

可以從實(shí)例發(fā)出多個(gè)請(qǐng)求那槽,它將自動(dòng)處理cookie和Referer標(biāo)頭悼沿。

注意:如果創(chuàng)建此HTTP請(qǐng)求是為了與生產(chǎn)出站適配器(EnsLib.HTTP.Outbound Adapter)一起使用,那么請(qǐng)改用該適配器的方法來(lái)發(fā)送請(qǐng)求骚灸。

  1. 如果需要糟趾,使用%Net.HttpRequest的同一實(shí)例發(fā)送其他HTTP請(qǐng)求。默認(rèn)情況下甚牲,InterSystems IRIS使TCP/IP套接字保持打開狀態(tài)义郑,以便可以重復(fù)使用套接字,而無(wú)需關(guān)閉和重新打開它丈钙。

以下是一個(gè)簡(jiǎn)單的示例:

/// w ##class(PHA.TEST.HTTP).Get()
ClassMethod Get()
{
    set request=##class(%Net.HttpRequest).%New()
    set request.Server="tools.ietf.org"
    set request.Https=1
    set request.SSLConfiguration="yx"
    set status=request.Get("/html/rfc7158")
    d $System.Status.DisplayError(status) 

    s response = request.HttpResponse
    s stream = response.Data
    q stream.Read()
}

提供身份驗(yàn)證

如果目標(biāo)服務(wù)器需要登錄憑據(jù)非驮,則HTTP請(qǐng)求可以包括提供憑據(jù)的HTTP Authorization標(biāo)頭。

如果使用的是代理服務(wù)器著恩,還可以指定代理服務(wù)器的登錄憑據(jù)院尔;為此蜻展,請(qǐng)?jiān)O(shè)置ProxyAuthorization屬性

使用HTTP 1.0時(shí)對(duì)請(qǐng)求進(jìn)行身份驗(yàn)證

對(duì)于HTTP 1.0,要驗(yàn)證HTTP請(qǐng)求邀摆,請(qǐng)?jiān)O(shè)置%Net.HttpRequest實(shí)例的用戶名和密碼屬性纵顾。然后,該實(shí)例使用基本訪問(wèn)身份驗(yàn)證基于該用戶名和密碼創(chuàng)建HTTP Authorization標(biāo)頭(RFC 2617)栋盹。此%Net.HttpRequest發(fā)送的任何后續(xù)請(qǐng)求都將包括此頭施逾。

重要提示:請(qǐng)確保還使用SSL。在基本身份驗(yàn)證中例获,憑據(jù)以base-64編碼形式發(fā)送汉额,因此易于讀取。

在使用HTTP 1.1時(shí)對(duì)請(qǐng)求進(jìn)行身份驗(yàn)證

對(duì)于HTTP 1.1榨汤,要驗(yàn)證HTTP請(qǐng)求蠕搜,在大多數(shù)情況下,只需設(shè)置%Net.HttpRequest實(shí)例的用戶名和密碼屬性收壕。當(dāng)%Net.HttpRequest的實(shí)例收到401 HTTP狀態(tài)代碼和WWW-Authenticate標(biāo)頭時(shí)妓灌,它會(huì)嘗試使用包含支持的身份驗(yàn)證方案的Authorization標(biāo)頭進(jìn)行響應(yīng)。使用為IRIS支持和配置的第一個(gè)方案蜜宪。默認(rèn)情況下虫埂,它按以下順序考慮這些身份驗(yàn)證方案:

  1. 協(xié)商(SPNEGO和Kerberos,根據(jù)RFC 4559和RFC 4178)
  2. NTLM(NT LAN Manager身份驗(yàn)證協(xié)議)
  3. 基本認(rèn)證(RFC 2617中描述的基本接入認(rèn)證)

重要:如果有可能使用基本身份驗(yàn)證圃验,請(qǐng)確保也使用SSL(參見“使用SSL進(jìn)行連接”)掉伏。
在基本身份驗(yàn)證中,憑據(jù)以base-64編碼的形式發(fā)送澳窑,因此很容易讀取斧散。

在Windows上,如果沒有指定Username屬性照捡,IRIS可以使用當(dāng)前登錄上下文颅湘。
具體來(lái)說(shuō),如果服務(wù)器使用401狀態(tài)碼和用于SPNEGO栗精、KerberosNTLMWWW-Authenticate頭響應(yīng)闯参,那么IRIS將使用當(dāng)前操作系統(tǒng)用戶名和密碼創(chuàng)建Authorization頭。

具體情況與HTTP 1.0不同悲立,如下所示:

  1. 如果認(rèn)證成功鹿寨,IRIS更新%NetCurrentAuthenticationScheme屬性。
    HttpRequest實(shí)例來(lái)指示它在最近的身份驗(yàn)證中使用的身份驗(yàn)證方案薪夕。
  2. 如果嘗試獲取方案的身份驗(yàn)證句柄或令牌失敗脚草,IRIS會(huì)將基礎(chǔ)錯(cuò)誤保存到%Net.HttpRequest實(shí)例的AuthenticationErrors屬性中。此屬性的值為$List原献,其中每一項(xiàng)都具有格式scheme ERROR: message

僅HTTP 1.1支持協(xié)商和NTLM馏慨,因?yàn)檫@些方案需要多次往返埂淮,而HTTP 1.0要求在每個(gè)請(qǐng)求/響應(yīng)對(duì)之后關(guān)閉連接。

Variations

如果知道服務(wù)器允許的一個(gè)或多個(gè)身份驗(yàn)證方案写隶,則可以通過(guò)包括Authorization標(biāo)頭來(lái)繞過(guò)服務(wù)器的初始往返行程倔撞,該標(biāo)頭包含所選方案的服務(wù)器的初始令牌。為此慕趴,請(qǐng)?jiān)O(shè)置%Net.HttpRequest實(shí)例的InitiateAuthentication屬性痪蝇。對(duì)于此屬性的值,請(qǐng)指定服務(wù)器允許的單個(gè)授權(quán)方案的名稱冕房。使用下列值之一(區(qū)分大小寫):

  • Negotiate
  • NTLM
  • Basic

如果要自定義要使用的身份驗(yàn)證方案(或更改其考慮順序)躏啰,請(qǐng)?jiān)O(shè)置%Net.HttpRequest實(shí)例的AuthenticationSchemes。對(duì)于此屬性的值耙册,請(qǐng)指定以逗號(hào)分隔的身份驗(yàn)證方案名稱列表(使用上一個(gè)列表中給出的準(zhǔn)確值)给僵。

直接指定授權(quán)標(biāo)頭

對(duì)于HTTP 1.0或HTTP 1.1(如果適用于場(chǎng)景),可以直接指定HTTP Authorization標(biāo)頭觅玻。具體地說(shuō)想际,可以將Authorization屬性設(shè)置為等于正在請(qǐng)求的資源的用戶代理所需的身份驗(yàn)證信息培漏。

如果指定Authorization屬性溪厘,則忽略用戶名和密碼屬性。

啟用HTTP身份驗(yàn)證的日志記錄

要啟用HTTP身份驗(yàn)證的日志記錄牌柄,請(qǐng)?jiān)诮K端中輸入以下內(nèi)容:

 set $namespace="%SYS"
 kill ^ISCLOG
 set ^%ISCLOG=2
 set ^%ISCLOG("Category","HttpRequest")=5

日志條目將寫入^ISCLOG global中.畸悬。要將日志寫入文件(以提高可讀性),請(qǐng)輸入以下內(nèi)容(仍在%SYS命名空間內(nèi)):

 do ##class(%OAuth2.Utils).DisplayLog("filename")

其中珊佣,filename是要?jiǎng)?chuàng)建的文件的名稱蹋宦。該目錄必須已存在。如果該文件已經(jīng)存在咒锻,它將被覆蓋冷冗。

要停止日志記錄,請(qǐng)輸入以下內(nèi)容(仍在%SYS命名空間內(nèi)):

 set ^%ISCLOG=0
 set ^%ISCLOG("Category","HttpRequest")=0

指定其他HTTP請(qǐng)求屬性

在發(fā)送HTTP請(qǐng)求之前(請(qǐng)參閱發(fā)送HTTP請(qǐng)求)惑艇,可以指定其屬性蒿辙,如以下各節(jié)所述:

可以為%Net.HttpRequest的所有屬性指定默認(rèn)值,如最后列出的部分中所指定滨巴。

Location屬性

Location屬性指定從Web服務(wù)器請(qǐng)求的資源思灌。如果設(shè)置此屬性,則在調(diào)用Get(), Head(), Post(), 或 Put()方法時(shí)恭取,可以省略location參數(shù)泰偿。

例如,假設(shè)正在向url http://machine_name/test/index.html發(fā)送一個(gè)HTTP請(qǐng)求

在這種情況下蜈垮,將使用下列值:

%Net.HttpRequest的示例屬性

Properties Value
Server machine_name
Location test/index.html

指定Internet媒體類型(Media Type)和字符編碼(Character Encoding)

可以使用以下屬性指定%Net.HttpRequest實(shí)例及其響應(yīng)中的Internet媒體類型(也稱為MIME類型)和字符編碼:

  • Content-Type指定Content-Type標(biāo)頭耗跛,該標(biāo)頭指定請(qǐng)求正文的Internet媒體類型裕照。默認(rèn)類型為None。

可能的值包括application/json调塌、application/pdf牍氛、application/postscriptimage/jpeg烟阐、image/png搬俊、multipart/form-datatext/html蜒茄、text/plan唉擂、text/xml等等

  • ContentCharset屬性控制請(qǐng)求的任何內(nèi)容(例如,text/htmltext/xml)類型時(shí)所需的字符集檀葛。如果不指定此屬性玩祟,InterSystems IRIS將使用InterSystems IRIS服務(wù)器的默認(rèn)編碼。

注意:如果設(shè)置此屬性屿聋,則必須首先設(shè)置ContentType屬性空扎。

  • NoDefaultContentCharset屬性控制在未設(shè)置ContentCharset屬性的情況下是否包括文本類型內(nèi)容的顯式字符集。默認(rèn)情況下润讥,此屬性為False转锈。

如果此屬性為true,則如果有文本類型的內(nèi)容楚殿,并且沒有設(shè)置ContentCharset屬性撮慨,則內(nèi)容類型中不包括任何字符集;這意味著字符集iso-8859-1用于消息輸出脆粥。

  • WriteRawMode屬性影響實(shí)體正文(如果包含)砌溺。它控制請(qǐng)求正文的寫入方式。默認(rèn)情況下变隔,此屬性為False规伐,并且InterSystems IRIS以請(qǐng)求標(biāo)頭中指定的編碼寫入正文。如果此屬性為true匣缘,則InterSystems IRIS以原始模式寫入正文(不執(zhí)行字符集轉(zhuǎn)換)猖闪。
  • ReadRawMode屬性控制如何讀取響應(yīng)正文。默認(rèn)情況下孵户,此屬性為False萧朝,并且InterSystems IRIS假定正文在響應(yīng)標(biāo)頭中指定的字符集中。如果此屬性為true夏哭,InterSystems IRIS將以原始模式讀取正文(不執(zhí)行字符集轉(zhuǎn)換)检柬。

使用代理服務(wù)器

可以通過(guò)代理服務(wù)器發(fā)送HTTP請(qǐng)求。要設(shè)置此設(shè)置,請(qǐng)指定HTTP請(qǐng)求的以下屬性:

  • ProxyServer指定要使用的代理服務(wù)器的主機(jī)名何址。如果此屬性不為空里逆,則將HTTP請(qǐng)求定向到此計(jì)算機(jī)。
  • ProxyPort指定代理服務(wù)器上要連接到的端口用爪。
  • ProxyAuthorization指定Proxy-Authorization標(biāo)頭原押,如果用戶代理必須使用代理驗(yàn)證其自身,則必須設(shè)置該標(biāo)頭偎血。對(duì)于該值诸衔,請(qǐng)使用正在請(qǐng)求的資源的用戶代理所需的身份驗(yàn)證信息。
  • ProxyHTTPS控制HTTP請(qǐng)求是針對(duì)HTTPS頁(yè)面還是針對(duì)普通HTTP頁(yè)面颇玷。如果未指定代理服務(wù)器笨农,則忽略此屬性。此屬性將目標(biāo)系統(tǒng)上的默認(rèn)端口更改為代理端口443帖渠。
  • ProxyTunes指定是否通過(guò)代理建立到目標(biāo)HTTP服務(wù)器的隧道谒亦。如果為true,則請(qǐng)求使用HTTP CONNECT命令建立隧道空郊。代理服務(wù)器的地址取自ProxyServerProxyPort屬性份招。如果ProxyHttps為true,則隧道建立后狞甚,系統(tǒng)間IRIS將協(xié)商SSL連接锁摔。在這種情況下,由于隧道與目標(biāo)系統(tǒng)建立直接連接入愧,因此將忽略https屬性鄙漏。

使用SSL進(jìn)行連接

%Net.HttpRequest類支持SSL連接。要通過(guò)SSL發(fā)送請(qǐng)求棺蛛,請(qǐng)執(zhí)行以下操作:

  1. SSLConfiguration屬性設(shè)置為要使用的已激活SSL/TLS配置的名稱。

  2. 還要執(zhí)行以下操作之一巩步,具體取決于是否使用代理服務(wù)器:

  • 如果未使用代理服務(wù)器旁赊,請(qǐng)將https屬性設(shè)置為true。
  • 如果使用的是代理服務(wù)器椅野,請(qǐng)將ProxyHTTPS屬性設(shè)置為true终畅。

在這種情況下,要使用到代理服務(wù)器本身的SSL連接竟闪,請(qǐng)將https屬性設(shè)置為true离福。

請(qǐng)注意,當(dāng)使用到給定服務(wù)器的SSL連接時(shí)炼蛤,該服務(wù)器上的默認(rèn)端口假定為443(HTTPS端口)妖爷。例如,如果沒有使用代理服務(wù)器理朋,并且https為true絮识,則會(huì)將Default Port屬性更改為443绿聘。

服務(wù)器身份檢查

默認(rèn)情況下,當(dāng)%Net.HttpRequest實(shí)例連接到SSL/TLS安全的Web服務(wù)器時(shí)次舌,它會(huì)檢查證書服務(wù)器名稱是否與用于連接到服務(wù)器的DNS名稱匹配熄攘。如果這些名稱不匹配,則不允許連接彼念。此默認(rèn)行為可防止“中間人”攻擊挪圾,在RFC 2818的3.1節(jié)中進(jìn)行了描述;另請(qǐng)參閱RFC 2595的2.4節(jié)逐沙。

若要禁用此檢查洛史,請(qǐng)將SSLCheckServerIdentity屬性設(shè)置為0。

HTTPVersion酱吝、Timeout也殖、WriteTimeoutFollowRedirect屬性

%Net.HttpRequest還提供以下屬性:

HTTPVersion指定請(qǐng)求頁(yè)面時(shí)使用的HTTP版本。默認(rèn)值是"HTTP/1.1"务热。你也可以使用“HTTP/1.0”忆嗜。

Timeout指定等待web服務(wù)器響應(yīng)的時(shí)間,以秒為單位崎岂。
缺省值是30秒捆毫。

WriteTimeout指定等待Web服務(wù)器完成寫入的時(shí)間(以秒為單位)。默認(rèn)情況下冲甘,它將無(wú)限期等待绩卤。可接受的最小值為2秒江醇。

FollowRedirect指定是否自動(dòng)跟蹤來(lái)自Web服務(wù)器的重定向請(qǐng)求(由300-399范圍內(nèi)的HTTP狀態(tài)代碼發(fā)出信號(hào))濒憋。如果使用的是GET或HEAD,則默認(rèn)值為TRUE陶夜;否則為FALSE凛驮。

指定HTTP請(qǐng)求的默認(rèn)值

可以為%Net.HttpRequest的所有屬性指定默認(rèn)值。

  • 要指定適用于所有名稱空間的默認(rèn)值条辟,請(qǐng)?jiān)O(shè)置全局節(jié) ^%SYS("HttpRequest","propname")黔夭,其中“PropName”是屬性的名稱。
  • 要為一個(gè)名稱空間指定默認(rèn)值羽嫡,請(qǐng)轉(zhuǎn)到該名稱空間并設(shè)置節(jié)點(diǎn)^SYS("HttpRequest","propname")

(^%SYS全局設(shè)置會(huì)影響整個(gè)安裝本姥,^SYS全局設(shè)置會(huì)影響當(dāng)前命名空間。)

例如杭棵,要為所有名稱空間指定默認(rèn)代理服務(wù)器婚惫,請(qǐng)?jiān)O(shè)置全局節(jié)^%SYS("HttpRequest","ProxyServer")

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子辰妙,更是在濱河造成了極大的恐慌鹰祸,老刑警劉巖,帶你破解...
    沈念sama閱讀 210,835評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件密浑,死亡現(xiàn)場(chǎng)離奇詭異蛙婴,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)尔破,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,900評(píng)論 2 383
  • 文/潘曉璐 我一進(jìn)店門街图,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人懒构,你說(shuō)我怎么就攤上這事餐济。” “怎么了胆剧?”我有些...
    開封第一講書人閱讀 156,481評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵絮姆,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我秩霍,道長(zhǎng)篙悯,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,303評(píng)論 1 282
  • 正文 為了忘掉前任铃绒,我火速辦了婚禮鸽照,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘颠悬。我一直安慰自己矮燎,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,375評(píng)論 5 384
  • 文/花漫 我一把揭開白布赔癌。 她就那樣靜靜地躺著诞外,像睡著了一般。 火紅的嫁衣襯著肌膚如雪届榄。 梳的紋絲不亂的頭發(fā)上浅乔,一...
    開封第一講書人閱讀 49,729評(píng)論 1 289
  • 那天,我揣著相機(jī)與錄音铝条,去河邊找鬼。 笑死席噩,一個(gè)胖子當(dāng)著我的面吹牛班缰,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播悼枢,決...
    沈念sama閱讀 38,877評(píng)論 3 404
  • 文/蒼蘭香墨 我猛地睜開眼埠忘,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起莹妒,我...
    開封第一講書人閱讀 37,633評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤名船,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后旨怠,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體渠驼,經(jīng)...
    沈念sama閱讀 44,088評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,443評(píng)論 2 326
  • 正文 我和宋清朗相戀三年鉴腻,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了迷扇。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,563評(píng)論 1 339
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡爽哎,死狀恐怖蜓席,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情课锌,我是刑警寧澤厨内,帶...
    沈念sama閱讀 34,251評(píng)論 4 328
  • 正文 年R本政府宣布,位于F島的核電站渺贤,受9級(jí)特大地震影響雏胃,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜癣亚,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,827評(píng)論 3 312
  • 文/蒙蒙 一丑掺、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧述雾,春花似錦街州、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,712評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至黍翎,卻和暖如春面徽,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背匣掸。 一陣腳步聲響...
    開封第一講書人閱讀 31,943評(píng)論 1 264
  • 我被黑心中介騙來(lái)泰國(guó)打工趟紊, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人碰酝。 一個(gè)月前我還...
    沈念sama閱讀 46,240評(píng)論 2 360
  • 正文 我出身青樓霎匈,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親送爸。 傳聞我的和親對(duì)象是個(gè)殘疾皇子铛嘱,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,435評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容