返回列表 發帖

jQuery Ajax 跨網域call web service遇到的問題

大家好,小弟不才要請教各位前輩一個問題,這問題在Google上查,好像很多人都有發生,而我依據網路上的作法去做,仍然無法順利取得資料,才斗膽上來發問.

這是一個透過送經緯度回傳地理資訊的web service.
一開始我是用以下的程式碼,在IE8上可順利取得.但用chrome就不行.
 <Script Language="JavaScript" type="text/javascript" src="jquery-1.2.6.js"></Script>
<script language="javascript" type="text/javascript"> 
function showMsg() {
        $.ajax({
              dataType: 'text',
              url: 'http://ngis.moea.gov.tw/ngisfxdata/webservice/XMLFunc_basic.aspx?cmd=basic&x=120.300249&y=22.612073&coor=84',
              type: 'get',
              success: function(oXml) {
                           $("#txt1").val(oXml);
                }
              })
            }
</script>
chrome會有Origin http://localhost is not allowed by Access-Control-Allow-Origin.的錯誤,查了網路說是安全性問題,所以必須要用以下解法:
1.加入以下header
    Access-Control-Allow-Origin: *
    Access-Control-Allow-Methods:GET,PUT,POST,DELETE
2.在執行chrome時加入--disable-web-security

但我在web.config裡加入以下也沒有用
<httpProtocol>
            <customHeaders>
                <add name="Access-Control-Allow-Origin" value="*" />
                <add name="Access-Control-Allow-Methods" value="GET,PUT,POST,DELETE" />
                <add name="Access-Control-Allow-Headers" value="Content-Type" />
            </customHeaders>
        </httpProtocol>
在$.Ajax裡加入以下也沒有用
 <Script Language="JavaScript" type="text/javascript" src="jquery-1.10.2.js"></Script>
<script language="javascript" type="text/javascript"> 
function showMsg() {
        $.ajax({
             beforeSend: function(xhrObj){  //加入這些
            xhrObj.setRequestHeader("Access-Control-Allow-Origin","*");//加入這些
            xhrObj.setRequestHeader("Access-Control-Allow-Methods","GET,PUT,POST,DELETE");//加入這些
            },
            headers: { 'Access-Control-Allow-Origin': '*' }, //加入這些
              dataType: 'text',
              url: 'http://ngis.moea.gov.tw/ngisfxdata/webservice/XMLFunc_basic.aspx?cmd=basic&x=120.300249&y=22.612073&coor=84',
              type: 'get',
              success: function(oXml) {
                           $("#txt1").val(oXml);
                }
              })
            }
</script>
在IIS裡的 預設的網站\HTTP標頭\自訂HTTP標頭 新增Access-Control-Allow-Origin: *, 也沒有用


只有在執行chrome時加入--disable-web-security時就能成功取得傳回的資料,不會有not allowed by Access-Control-Allow-Origin.的錯誤
但不可能寫一個網頁,要叫每個使用者都要用帶參數的方式執行chrome吧,而且我是要用手機連的,手機上的chrome,safari也不能這樣執行.
所以就再找解決方法,後來有高手建議要把datatype改成JSONP

所以,我就把程式改成以下.
 <Script Language="JavaScript" type="text/javascript" src="jquery-1.10.2.js"></Script>
<script language="javascript" type="text/javascript"> 
function showMsg() {
        $.ajax({
              dataType: 'jsonp',
              crossDomain: true,
              url: 'http://ngis.moea.gov.tw/ngisfxdata/webservice/XMLFunc_basic.aspx?cmd=basic&x=120.300249&y=22.612073&coor=84',
              type: 'get',
              success: function() {
                          alert("Success");
                }
              })
            }
</script>
但得到的結果還是取不到,錯誤訊息是
Resource interpreted as Script but transferred with MIME type text/xml: "http://ngis.moea.gov.tw/ngisfxdata/webservice/XMLFunc_basic.aspx?cmd=basic&…coor=84&callback=jQuery110203576156080234796_1383033330407&_=1383033330408".
Uncaught SyntaxError: Unexpected token <

但由chrome 檢查元素裡的Network去看Response是有回傳XML字串的.但就是有以上的錯誤,無法承接.
所以只好厚著臉皮上來請教一下各位,我用Google大神查兩天了.還是無法解決,謝謝先.

回復 1# scfmailkimo

跨網域 call web service 需要提供服務端的配合,不然就得透過自己的 server 處理。
你前面提到的兩種方式不行的原因:
1. Access-Control-Allow-Origin: * 是要加在提供服務端的 response,不是你自己的程式。
2. JSONP 也是服務端得配合接收 callback 參數,並且把資料給包裝成 JSON 格式。

因為你有 IIS Server,可以先透過你 server 端的程式(asp.net?)去抓資料,
再讓自己的 JavaScript 來 call 即可。
To infinity and beyond!

TOP

感謝wmh大,

原來是要加在提供服務的那端哦,但這樣我覺得不太合理啊,通常跨網域的應該都是別人的網站,要求提供服務的人加上那段,別人不一定會答應啊,而且我用IE或chrome --disable-web-security就能取得到,感覺起來是client端就能解決的事,真的有些事不是我這種憨人想得到的.

另外,用 JSONP 的方式,確實在它送參數時有帶jQuery11020357.....,但服務端對這個參數應該是無感,不過我看服務端也respone正確的xml字串回來,只是我的網頁有錯誤訊息,不知如何去接(由chrome檢查元素裡去看).

我一開始是可以用asp.net 透過System.Net.WebClient()去取得web service(xml)的.不過我需要的是client side就能取得到,所以才再找javascript和jQuery來作. 所以wmh大的意思是,我寫一個asmx跨網域去取,然後我的javascript再去call這個本地端的web service(asmx)嗎?  謝謝

TOP

回復 3# scfmailkimo

嗯,透過 jQuery 取自己 server 端的程式,自己 server 端的程式再發 request 去抓遠端的資料。
To infinity and beyond!

TOP

謝謝wmh大,依照你的建議已搞定。謝謝。

TOP

返回列表 回復 發帖