最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

分享XmlHttpRequest調(diào)用Webservice的一點心得

 更新時間:2012年07月20日 20:01:18   作者:  
因為項目需要,以后前端、手機客戶端調(diào)用ASP.NET的Webservice來獲取信息.所以這段時間開始看Webservice,試著通過XmlHttpRequest調(diào)用Webservice,過程中碰到不少問題,也有不少的收獲
首先,因為JSON對于JS的便利性,考慮通過JSON來請求和返回數(shù)據(jù)。在JS中實例化一個xmlHttpRequest對象,然后根據(jù)網(wǎng)上的說明POST的地址為:asmx頁面地址/Web方法名。在RequestHeader中設置Content-Type為application/json; charset=utf-8,SOAPAction設為Web方法名。Web方法的參數(shù)用JSON格式send出去。
代碼如下:
復制代碼 代碼如下:

function getXmlHttp() {
var xmlHttp;
if (window.XMLHttpRequest)
{ // code for IE7+, Firefox, Chrome, Opera, Safari
xmlHttp = new XMLHttpRequest();
}
else
{ // code for IE6, IE5
xmlHttp = new ActiveXObject('Microsoft.XMLHTTP');
}
return xmlHttp;
}
function webservice(url, action, data, success, error, complete, failed) {
var xmlHttp = getXmlHttp(); //獲取XMLHttpRequest對象
xmlHttp.open('POST', url + '/' + action, true); //異步請求數(shù)據(jù)
xmlHttp.onreadystatechange = function () {
if (xmlHttp.readyState == 4) {
try {
if (xmlHttp.status == 200 && typeof (success) == 'function') {
success(xmlHttp.responseText);
}
else if ((xmlHttp.status / 100 == 4 || xmlHttp.status / 100 == 5) && typeof (error) == 'function') {
error(xmlHttp.responseText, xmlHttp.status);
}
else if (xmlHttp.status / 100 == 200 && typeof (complete) == 'function') {
complete(xmlHttp.responseText, xmlHttp.status);
}
else if (typeof (failed) == 'function') {
failed(xmlHttp.responseText, xmlHttp.status);
}
}
catch (e) {
}
}
}
xmlHttp.setRequestHeader('Content-Type', 'application/json; charset=utf-8');
xmlHttp.setRequestHeader('SOAPAction', action);
xmlHttp.send(data);
}

比如請求調(diào)用Webservice1中的HelloWorld方法:
復制代碼 代碼如下:

webservice('/Webservice1.asmx','HelloWorld','{}',function (msg) { alert(msg); });

調(diào)用前請記得把Webservice1上面的 [System.Web.Script.Services.ScriptService] 取消注釋,調(diào)用后可以看到彈出警告窗口:{"d": "Hello World"}。把Content-Type設為text/xml時,警告窗口的內(nèi)容變就變成了<?xml version="1.0" encoding="utf-8"?> <string xmlns="http://tempuri.org/">Hello World</string>。
這時候雖然參數(shù)“{}”還是JSON的形式請求卻是XML格式,但因為Hello World沒有參數(shù),所以忽略了內(nèi)容的格式,能夠正常返回值。
如果修改服務端的HelloWorld方法,添加一個string類型的參數(shù)somebody。
復制代碼 代碼如下:

[WebMethod]
public string HelloWorld(string somebody) {
return "Hello World&Hello, " + somebody + "!";
}

將請求端的Content-Type改回application/json,傳送參數(shù)改為{"somebody": "Krime"},調(diào)用后彈出窗口內(nèi)容變?yōu)閧d: "Hello World&Hello, Krime!"}。
但如果這時再直接把Content-Type改為text/xml,調(diào)用后服務器將會報錯:System.InvalidOperationException: 請求格式無效: text/xml; charset=UTF-8。 在 System.Web.Services.Protocols.HttpServerProtocol.ReadParameters() 在 System.Web.Services.Protocols.WebServiceHandler.CoreProcessRequest()
于是我們把參數(shù)格式也修改一下,按照Webservice調(diào)試頁面的示例,將參數(shù)改為:
復制代碼 代碼如下:

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<HelloWorld xmlns="http://tempuri.org/">
<somebody>Krime</somebody>
</HelloWorld>
</soap:Body>
</soap:Envelope>

這樣應該就能正常返回XML的結果了吧?結果卻出乎意料,服務器仍然報同樣的錯誤。
折騰了很久后,幾乎要抓狂了,難道ASP.NET突然不認識XML了?這個時候,再回去仔細看看Webservice調(diào)試頁面的示例,終于發(fā)現(xiàn)了一點問題:
復制代碼 代碼如下:

POST /WebServiceTest/Webservice1.asmx HTTP/1.1
Host: localhost
Content-Type: text/xml; charset=utf-8
Content-Length: length
SOAPAction: "http://tempuri.org/HelloWorld"
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<HelloWorld xmlns="http://tempuri.org/">
<somebody>string</somebody>
</HelloWorld>
</soap:Body>
</soap:Envelope>

上面POST的地址后面并沒有像請求JSON數(shù)據(jù)時一樣加上/方法名,而SOAPAction的方法名前面還需要加上命名空間。于是修改XMLHttpRequest的請求頭,url和action做相應修改,結果終于正常返回了XML的結果:<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body><HelloWorldResponse xmlns="http://tempuri.org/"><HelloWorldResult>Hello World&Hello, Krime!</HelloWorldResult></HelloWorldResponse></soap:Body></soap:Envelope>
后來繼續(xù)測試,發(fā)現(xiàn)請求內(nèi)容類型為application/json時,SOAPAction完全可以忽略不加,但是url后面一定要加上/方法名,否則服務器不會返回數(shù)據(jù)。而請求text/xml時,SOAPAction是必須的且前面要加上命名空間,url后面則不能有/方法名。
最后,經(jīng)過總結,將代碼改成了最終的樣子:
復制代碼 代碼如下:

function getXmlHttp() {
var xmlHttp;
if (window.XMLHttpRequest)
{ // code for IE7+, Firefox, Chrome, Opera, Safari
xmlHttp = new XMLHttpRequest();
}
else
{ // code for IE6, IE5
xmlHttp = new ActiveXObject('Microsoft.XMLHTTP');
}
return xmlHttp;
}
function webservice(url, options) {
if (typeof (url) == 'object') { //將url寫在options里的情況
options = url;
url = url.url;
}
if (!url) return;
if (options.dataType.toLowerCase() == 'json') { //請求JSON格式的數(shù)據(jù)時,url后面需要加上“/方法名”
url = url + '/' + options.method;
}
var xmlHttp = getXmlHttp(); //獲取XMLHttpRequest對象
xmlHttp.open('POST', url, true); //異步請求數(shù)據(jù)
xmlHttp.onreadystatechange = function () {
if (xmlHttp.readyState == 4) {
try {
if (xmlHttp.status == 200 && typeof (options.success) == 'function') {
options.success(xmlHttp.responseText);
}
else if ((xmlHttp.status / 100 == 4 || xmlHttp.status / 100 == 5) && typeof (options.error) == 'function') {
options.error(xmlHttp.responseText, xmlHttp.status);
}
else if (xmlHttp.status / 100 == 200 && typeof (options.complete) == 'function') {
options.complete(xmlHttp.responseText, xmlHttp.status);
}
else if (typeof (options.failed) == 'function') {
options.failed(xmlHttp.responseText, xmlHttp.status);
}
}
catch (e) {
}
}
}
xmlHttp.setRequestHeader('Content-Type', options.contentType); //設置請求頭的ContentType
xmlHttp.setRequestHeader('SOAPAction', options.namespace + options.method); //設置SOAPAction
xmlHttp.send(options.data); //發(fā)送參數(shù)數(shù)據(jù)
}

請求JSON數(shù)據(jù):
復制代碼 代碼如下:

window.onload = function () {
var data = '{"somebody": "Krime"}';
var options = {
namespace: 'http://tempuri.org/',
method: 'HelloWorld',
contentType: 'application/json; charset=utf-8',
dataType: 'json',
data: data,
success: function (msg) {
alert(msg);
}
};
webservice('http://localhost:8003/WebServiceTest/Webservice1.asmx', options);
};

請求XML數(shù)據(jù):
復制代碼 代碼如下:

window.onload = function () {
var data = '<?xml version="1.0" encoding="utf-8"?>'
+ '<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">'
+ '<soap:Body>'
+ '<HelloWorld xmlns="http://tempuri.org/">'
+ '<somebody>Krime</somebody>'
+ '</HelloWorld>'
+ '</soap:Body>'
+ '</soap:Envelope>';
var options = {
namespace: 'http://tempuri.org/',
method: 'HelloWorld',
contentType: 'text/xml; charset=utf-8',
dataType: 'xml',
data: data,
success: function (msg) {
alert(msg);
}
};
webservice('http://localhost:8003/WebServiceTest/Webservice1.asmx', options);
};

測試情況正常。
需要注意的一點是,請求JSON數(shù)據(jù)時,如果返回類型是DataTable是不行的,需要轉換成相應數(shù)據(jù)實體類的List<>再返回。

在解決返回XML問題的過程中,還找到另一種解決方法。具體操作時,是將ContentType設為application/x-www-form-urlencoded,數(shù)據(jù)體不用JSON也不用XML格式的SOAP包,而是用類似QueryString的“arguement1=XXX&arguement2=XXX”。這個方法是模擬了窗體數(shù)據(jù)的HTTP POST格式,將每個控件值編碼為名稱=值對發(fā)送出去。

這種情況下的頁面地址后面也需要加上/方法名。

相關文章

  • javascript閉包的理解和實例

    javascript閉包的理解和實例

    所謂閉包,值得是詞法表示包括不必要計算的變量的函數(shù),也就是說,該函數(shù)可以使用函數(shù)外定義的變量。
    2010-08-08
  • 原生JS實現(xiàn)網(wǎng)頁手機音樂播放器 歌詞同步播放的示例

    原生JS實現(xiàn)網(wǎng)頁手機音樂播放器 歌詞同步播放的示例

    下面小編就為大家分享一篇原生JS實現(xiàn)網(wǎng)頁手機音樂播放器 歌詞同步播放的示例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-02-02
  • 微信小程序中this.data與this.setData的區(qū)別詳解

    微信小程序中this.data與this.setData的區(qū)別詳解

    這篇文章主要給大家介紹了關于微信小程序中this.data與this.setData區(qū)別的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面來一起看看吧
    2018-09-09
  • 關閉時刷新父窗口兩種方法

    關閉時刷新父窗口兩種方法

    這篇文章主要介紹了刷新父窗口兩種方法,需要的朋友可以參考下
    2014-05-05
  • JavaScript面試之如何實現(xiàn)數(shù)組拍平(扁平化)方法

    JavaScript面試之如何實現(xiàn)數(shù)組拍平(扁平化)方法

    數(shù)組扁平化是指將一個多維數(shù)組變?yōu)橐痪S數(shù)組,下面這篇文章主要給大家介紹了關于JavaScript面試之如何實現(xiàn)數(shù)組拍平(扁平化)方法的相關資料,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考下
    2021-11-11
  • JavaScript避免回調(diào)地獄的策略分享

    JavaScript避免回調(diào)地獄的策略分享

    在JavaScript中,異步操作通常通過回調(diào)函數(shù)來處理,但當存在多個嵌套異步調(diào)用時,就會出現(xiàn)“回調(diào)地獄”(Callback Hell),避免回調(diào)地獄有助于提升代碼可讀性和可維護性,并使錯誤處理更為集中和規(guī)范,本文小編給大家介紹了JavaScript避免回調(diào)地獄的策略,需要的朋友可以參考下
    2025-03-03
  • js使用正則表達式對身份證號的判斷

    js使用正則表達式對身份證號的判斷

    這篇文章主要給大家介紹了關于js使用正則表達式對身份證號的判斷的相關資料,在用戶注冊頁面有些需求要求的比較嚴格,需要對身份證驗證是否合法,通過此功能嚴格此系統(tǒng)軟件,從而過濾到很多,需要的朋友可以參考下
    2023-08-08
  • 理解javascript中的回調(diào)函數(shù)(callback)

    理解javascript中的回調(diào)函數(shù)(callback)

    這篇文章主要介紹了理解javascript中的回調(diào)函數(shù)(callback),本文著重于對回調(diào)函數(shù)概念的理解,需要的朋友可以參考下
    2014-09-09
  • JS猜數(shù)字游戲?qū)嵗v解

    JS猜數(shù)字游戲?qū)嵗v解

    這篇文章主要為大家詳細介紹了JS猜數(shù)字游戲?qū)嵗?,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-06-06
  • 輕松理解JavaScript之AJAX

    輕松理解JavaScript之AJAX

    本文主要介紹了JavaScript中的AJAX的相關知識,具有很好的參考價值,下面跟著小編一起來看下吧
    2017-03-03

最新評論

镇雄县| 鲁甸县| 湛江市| 托里县| 榆林市| 神池县| 大荔县| 皮山县| 封丘县| 正镶白旗| 新密市| 宜黄县| 东阿县| 鄂托克旗| 乐东| 仁怀市| 宣汉县| 洛宁县| 河间市| 大邑县| 曲阜市| 鞍山市| 望城县| 海伦市| 阳春市| 庆城县| 澄迈县| 新河县| 奉新县| 托克逊县| 大洼县| 荥阳市| 中山市| 迭部县| 宁海县| 岚皋县| 玉山县| 开阳县| 库伦旗| 大宁县| 涞源县|