2010-09-30 121 views
55

我試圖從「遠程」網站獲取一些json數據。 我在99000端口上運行我的Web服務,然後在99001端口上啓動我的網站(http:// localhost:99001/index.html)。XMLHttpRequest無法使用jQuery加載URL

我得到以下信息:

XMLHttpRequest cannot load http://localhost:99000/Services.svc/ReturnPersons. Origin http://localhost:99001 is not allowed by Access-Control-Allow-Origin. 

即使我啓動我的網頁爲HTML文件時,我得到這個:

XMLHttpRequest cannot load http://localhost:99000/Services.svc/ReturnPersons.Origin null is not allowed by Access-Control-Allow-Origin. 

Web服務返回的數據。我試圖抓住的數據項是這樣的:

var url = "http://localhost:99000/Services.svc/ReturnPersons"; 
$.getJSON(url, function (data) { 
success: readData(data) 
}); 
function readData(data) { 
    alert(data[0].FirstName); 
} 

而我試圖讓這個結構:

[{"FirstName":"Foo","LastName":"Bar"},{"Hello":"Foo","LastName":"World"}] 

你知道爲什麼我得到這個錯誤?

回答

39

你不能做一個XMLHttpRequest的跨域,唯一的「選項」將是一個叫做JSONP技術,它可以歸結爲:

要開始請求:添加新<script>標籤與遠程URL,並然後確保遠程URL返回一個調用您的回調函數的有效JavaScript文件。一些服務支持這一點(並讓你在GET參數中命名你的回調)。

另一個簡單的方法是,在您的本地服務器上創建一個「代理」,該代理獲取遠程請求,然後將它「轉發」回您的javascript。

編輯/添加:

我看到的jQuery已經內置了對JSONP支持,通過檢查URL中包含 「?回調=」 (jQuery將用實際的回調方法替換?)。但是你仍然需要在遠程服務器上處理它以生成有效的響應。

+9

我通過添加「&callback =?」解決了這個問題。到URL。謝謝! – Zakaria 2010-09-30 09:58:45

+0

我是否必須在遠程服務器上的服務器腳本中指定/實現任何內容? – j7nn7k 2011-08-01 13:49:57

+0

是的,你的服務器通常返回一個JSON字符串,例如'{「foo」:「bar」}''''''''''''''''''''''''''''''''''''''''''例如'myFunction({「foo」:「bar」});' – CharlesLeaf 2011-08-02 12:36:50

33

在新的jQuery 1.5,你可以使用:

$.ajax({ 
    type: "GET", 
    url: "http://localhost:99000/Services.svc/ReturnPersons", 
    dataType: "jsonp", 
    success: readData(data), 
    error: function (xhr, ajaxOptions, thrownError) { 
     alert(xhr.status); 
     alert(thrownError); 
    } 
}) 
+4

它不應該只是「成功:readData」嗎? – 2013-03-18 03:47:10

+2

我得到了一個錯誤,因爲SyntaxError:意外的令牌: – 2015-07-22 07:48:24

+0

我是,在你的迴應中猜測它是額外的「:」。你能粘貼整個信息嗎? – Slavomir 2015-07-24 03:20:30

19

Fiddle with 3 working solutions在行動。

鑑於外部JSON:

myurl = 'http://wikidata.org/w/api.php?action=wbgetentities&sites=frwiki&titles=France&languages=zh-hans|zh-hant|fr&props=sitelinks|labels|aliases|descriptions&format=json' 

解決方案1:$就()+ JSONP:

$.ajax({ 
    dataType: "jsonp", 
    url: myurl , 
    }).done(function (data) { 
    // do my stuff 
}); 

解決方案2:$就()+ JSON + & calback = ?:

$.ajax({ 
    dataType: "json", 
    url: myurl + '&callback=?', 
    }).done(function (data) { 
    // do my stuff 
}); 

解決方案3:$ .getJSON()+ calback =?:

$.getJSON(myurl + '&callback=?', function(data) { 
    // do my stuff 
}); 

之證件:http://api.jquery.com/jQuery.ajax/http://api.jquery.com/jQuery.getJSON/

+0

JSfiddle修復了以下內容#wikidata API更改,jsfiddle改進完成,編輯改進完成! – Hugolpz 2013-10-24 14:21:16

+0

在** HTTPS中無效**點擊鏈接查看https://jsfiddle.net/HNPyc/98/ – 2016-12-07 11:53:38

+1

@TuhinPaul:當你在** https **小提琴時,你不能請求** http * * wikidata或其他http,這將是一個安全漏洞。您可以執行http-http,https-https或http-https,而不是https-http。這是一項安全功能,不是跨域問題。 – Hugolpz 2016-12-07 15:47:46

6

發現了一個可能的解決方法,我不相信有人提到。

這是問題的一個很好的說明: http://www.asp.net/web-api/overview/security/enabling-cross-origin-requests-in-web-api

基本上只要你使用表單/ URL編碼/純文本內容類型你的罰款。

$.ajax({ 
    type: "POST", 
    headers: { 
     'Accept': 'application/json', 
     'Content-Type': 'text/plain' 
    }, 
    dataType: "json", 
    url: "http://localhost/endpoint", 
    data: JSON.stringify({'DataToPost': 123}), 
    success: function (data) { 
     alert(JSON.stringify(data)); 
    } 
});  

我在ASP.NET WebAPI2中使用它。所以在另一端:

public static void RegisterWebApi(HttpConfiguration config) 
{ 
    config.MapHttpAttributeRoutes(); 

    config.Formatters.Clear(); 
    config.Formatters.Add(new JsonMediaTypeFormatter()); 

    config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/plain")); 
} 

這樣的方式JSON格式化程序在解析純文本內容類型時使用。

,做在Web.config中不要忘記:

<system.webServer> 
<httpProtocol> 
    <customHeaders> 
    <add name="Access-Control-Allow-Origin" value="*" /> 
    <add name="Access-Control-Allow-Methods" value="GET, POST" /> 
    </customHeaders> 
</httpProtocol>  

希望這有助於。

0

我正在使用WebAPI 3並面臨同樣的問題。這個問題已經解決了,因爲@Rytis增加了他的解決方案。我想在WebAPI 3中,我們不需要定義方法RegisterWebApi

我的更改只在web.config文件中並且正在工作。

<httpProtocol> 
<customHeaders> 
<add name="Access-Control-Allow-Origin" value="*" /> 
<add name="Access-Control-Allow-Methods" value="GET, POST" /> 
</customHeaders> 
</httpProtocol> 

感謝您的解決方案@Rytis!