2013-02-21 61 views
102

我試圖使用AJAX加載跨域HTML頁面,但除非數據類型是「jsonp」,否則我無法獲得響應。然而,使用jsonp瀏覽器期待腳本MIME類型,但接收「文本/ HTML」。使用jQuery加載跨域端點AJAX

我的請求代碼是:

$.ajax({ 
    type: "GET", 
    url: "http://saskatchewan.univ-ubs.fr:8080/SASStoredProcess/do?_username=DARTIES3-2012&[email protected]&_program=%2FUtilisateurs%2FDARTIES3-2012%2FMon+dossier%2Fanalyse_dc&annee=2012&ind=V&_action=execute", 
    dataType: "jsonp", 
}).success(function(data) { 
    $('div.ajax-field').html(data); 
}); 

是否有使用JSONP的請求,避免的方法嗎?我已經嘗試過使用crossDomain參數,但它不起作用。

如果不是有什麼方法可以接收jsonp中的html內容嗎?目前控制檯在jsonp回覆中說「意外的<」。

回答

191

jQuery的阿賈克斯注

  • 由於瀏覽器的安全限制,大多數阿賈克斯請求都受到了same origin policy;該請求無法成功從不同的域,子域,端口或協議中檢索數據。
  • 腳本和JSONP請求不受相同的源策略限制。

有克服跨域屏障的一些方法:

有一些插件,與跨幫助 - 域個請求:

注意!

克服這個問題的最好辦法,就是通過在後臺建立自己的代理,讓代理將指向其他領域的服務,因爲在後端不存在相同的起源政策限制。但是如果你不能在後端做到這一點,那麼請注意以下提示。


警告!

使用第三方代理不是一個安全的做法,因爲他們可以跟蹤你的數據,所以它可以用公共信息中使用,但從來沒有私人數據。


下面使用所示的代碼示例jQuery.get()jQuery.getJSON(),兩者都是的jQuery.ajax()

速記方法


CORS Anywhere的

CORS Anywhere是一個node.js代理它將CORS頭添加到代理請求。
要使用API​​,只需在URL前加上URL即可。 (支持HTTPS:看github repository

如果你想自動啓用跨域請求需要的時候,可以使用下面的代碼片段:

$.ajaxPrefilter(function (options) { 
    if (options.crossDomain && jQuery.support.cors) { 
    var http = (window.location.protocol === 'http:' ? 'http:' : 'https:'); 
    options.url = http + '//cors-anywhere.herokuapp.com/' + options.url; 
    //options.url = "http://cors.corsproxy.io/url=" + options.url; 
    } 
}); 

$.get(
    'http://en.wikipedia.org/wiki/Cross-origin_resource_sharing', 
    function (response) { 
     console.log("> ", response); 
     $("#viewer").html(response); 
}); 


無論產地

Whatever Origin是一個跨域jsonp訪問。這是anyorigin.com的開源替代品。

google.com,取數據,你可以使用這個片段:

// It is good specify the charset you expect. 
// You can use the charset you want instead of utf-8. 
// See details for scriptCharset and contentType options: 
// http://api.jquery.com/jQuery.ajax/#jQuery-ajax-settings 
$.ajaxSetup({ 
    scriptCharset: "utf-8", //or "ISO-8859-1" 
    contentType: "application/json; charset=utf-8" 
}); 

$.getJSON('http://whateverorigin.org/get?url=' + 
    encodeURIComponent('http://google.com') + '&callback=?', 
    function (data) { 
     console.log("> ", data); 

     //If the expected response is text/plain 
     $("#viewer").html(data.contents); 

     //If the expected response is JSON 
     //var response = $.parseJSON(data.contents); 
}); 


CORS代理

CORS代理是一個簡單的的node.js代理爲任何網站啓用CORS請求。 它允許您網站上的JavaScript代碼訪問其他域上的資源,這些資源通常會因同源策略而被阻止。

它是如何工作的? CORS代理利用跨源資源共享,這是一項與HTML 5一起添加的功能。服務器可以指定他們希望瀏覽器允許其他網站請求他們託管的資源。 CORS Proxy只是一個HTTP代理服務器,它在響應中添加一個標題,標明「任何人都可以請求這個」。

這是實現此目標的另一種方式(請參見www.corsproxy.com)。所有你需要做的是剝離http://www。從URL被代理,並與www.corsproxy.com/

$.get(
    'http://www.corsproxy.com/' + 
    'en.wikipedia.org/wiki/Cross-origin_resource_sharing', 
    function (response) { 
     console.log("> ", response); 
     $("#viewer").html(response); 
}); 


CORS代理瀏覽器預先設置URL

最近我發現這一個,它涉及到各種安全導向的跨源遠程共享工具。但它是一個以Flash作爲後端的黑盒子。

你可以看到它在這裏的行動:CORS proxy browser
獲取GitHub上的源代碼:koto/cors-proxy-browser

+4

您也可以從這裏部署您自己的WhateverOrigin.org版本(或自行使用的代碼):https://github.com/ripper234/Whatever-Origin/ – EpicVoyage 2013-11-17 14:18:33

+0

我已經試過這段代碼,它工作正常從跨域加載HTML,但請求的HTML包含未加載響應的圖像。意味着返回的跨域請求的HTML不包含圖像。有沒有什麼辦法來加載圖像也????? – Hitesh 2014-01-21 11:39:10

+1

圖像,CSS和外部JavaScript可以從另一個來源引用,因此,在響應中,您可以通過HTML字符串並替換外部資源的src – jherax 2014-01-21 17:00:19

9

如果外部站點不支持JSONP或CORS,則唯一的選擇是使用代理。

在請求該內容的服務器上構建一個腳本,然後使用jQuery ajax命中服務器上的腳本。

19

您可以使用Ajax的跨域一個jQuery插件。 使用此插件,您可以使用jQuery.ajax()跨域。它使用谷歌的服務來實現這一目標:

的AJAX跨源插件使用谷歌Apps腳本作爲代理JSON 吸氣其中JSONP未實現。當您將crossOrigin 選項設置爲true時,插件會將原始網址替換爲Google地址,並將其作爲編碼的url參數發送。 Google腳本使用Google服務器資源獲取遠程數據,然後 將其作爲JSONP返回給客戶端。

這是非常簡單易用:

$.ajax({ 
     crossOrigin: true, 
     url: url, 
     success: function(data) { 
      console.log(data); 
     } 
    }); 

你可以在這裏閱讀更多: http://www.ajax-cross-origin.com/

+12

就我而言,這個插件從來沒有工作。它在Chrome上不會執行任何操作。 – Michael 2014-08-29 11:19:37

+0

如何驗證服務器? – sttaq 2015-04-23 15:11:52

+2

放入'http:// google.com'將無法使用此解決方案。 – Adam 2016-01-05 06:40:25

-7

想通了。 改用此。

$('.div_class').load('http://en.wikipedia.org/wiki/Cross-origin_resource_sharing #toctitle'); 
+0

你在那裏使用的代碼是無關緊要的。重要的是服務器端CORS頭。 – Quentin 2015-06-16 12:49:02

0

我發佈這個以防萬一有人面臨我現在面臨的同樣的問題。我有一臺配有ZebraNet打印服務器的Zebra熱敏打印機,它提供了一個基於HTML的用戶界面,用於編輯多個設置,查看打印機的當前狀態等。我需要獲取打印機的狀態在ZebraNet服務器提供的那些html頁面之一中,例如,在瀏覽器中向用戶發送alert()消息。這意味着我必須先使用Javascript獲取該頁面。儘管打印機位於用戶PC的局域網內,但這個Same Origin Policy仍然在我的路上。我嘗試過JSONP,但服務器返回HTML,但我還沒有找到修改其功能的方法(如果可以的話,我已經設置了魔法標頭Access-control-allow-origin:*)。所以我決定用C#編寫一個小型控制檯應用程序。它必須以管理員身份運行才能正常工作,否則它會投降:D是一個例外。以下是一些代碼:

// Create a listener. 
     HttpListener listener = new HttpListener(); 
     // Add the prefixes. 
     //foreach (string s in prefixes) 
     //{ 
     // listener.Prefixes.Add(s); 
     //} 
     listener.Prefixes.Add("http://*:1234/"); // accept connections from everywhere, 
     //because the printer is accessible only within the LAN (no portforwarding) 
     listener.Start(); 
     Console.WriteLine("Listening..."); 
     // Note: The GetContext method blocks while waiting for a request. 
     HttpListenerContext context; 
     string urlForRequest = ""; 

     HttpWebRequest requestForPage = null; 
     HttpWebResponse responseForPage = null; 
     string responseForPageAsString = ""; 

     while (true) 
     { 
      context = listener.GetContext(); 
      HttpListenerRequest request = context.Request; 
      urlForRequest = request.RawUrl.Substring(1, request.RawUrl.Length - 1); // remove the slash, which separates the portNumber from the arg sent 
      Console.WriteLine(urlForRequest); 

      //Request for the html page: 
      requestForPage = (HttpWebRequest)WebRequest.Create(urlForRequest); 
      responseForPage = (HttpWebResponse)requestForPage.GetResponse(); 
      responseForPageAsString = new StreamReader(responseForPage.GetResponseStream()).ReadToEnd(); 

      // Obtain a response object. 
      HttpListenerResponse response = context.Response; 
      // Send back the response. 
      byte[] buffer = System.Text.Encoding.UTF8.GetBytes(responseForPageAsString); 
      // Get a response stream and write the response to it. 
      response.ContentLength64 = buffer.Length; 
      response.AddHeader("Access-Control-Allow-Origin", "*"); // the magic header in action ;-D 
      System.IO.Stream output = response.OutputStream; 
      output.Write(buffer, 0, buffer.Length); 
      // You must close the output stream. 
      output.Close(); 
      //listener.Stop(); 

所有用戶需要做的就是以管理員身份運行該控制檯應用程序。我知道這也太...令人沮喪和複雜,但是如果您無法以任何方式修改服務器,它就是域策略問題的解決方法。

編輯:從JS我做一個簡單的Ajax調用:

$.ajax({ 
       type: 'POST', 
       url: 'http://LAN_IP:1234/http://google.com', 
       success: function (data) { 
        console.log("Success: " + data); 
       }, 
       error: function (e) { 
        alert("Error: " + e); 
        console.log("Error: " + e); 
       } 
      }); 

請求頁面的HTML被返回並存儲在數據變量。

-2

您需要CORS代理服務器代理您的請求從您的瀏覽器到適當的CORS headers請求的服務。這些服務的列表在下面的代碼片段中。您也可以運行提供的代碼片段查看您所在位置的此類服務。

$('li').each(function() { 
 
    var self = this; 
 
    ping($(this).text()).then(function(delta) { 
 
    console.log($(self).text(), delta, ' ms'); 
 
    }); 
 
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<script src="https://cdn.rawgit.com/jdfreder/pingjs/c2190a3649759f2bd8569a72ae2b597b2546c871/ping.js"></script> 
 
<ul> 
 
    <li>https://crossorigin.me/</li> 
 
    <li>https://cors-anywhere.herokuapp.com/</li> 
 
    <li>http://cors.io/</li> 
 
    <li>https://cors.5apps.com/?uri=</li> 
 
    <li>http://whateverorigin.org/get?url=</li> 
 
    <li>https://anyorigin.com/get?url=</li> 
 
    <li>http://corsproxy.nodester.com/?src=</li> 
 
    <li>https://jsonp.afeld.me/?url=</li> 
 
    <li>http://benalman.com/code/projects/php-simple-proxy/ba-simple-proxy.php?url=</li> 
 
</ul>

+11

這不會以任何方式回答問題。 – 0xc0de 2016-09-06 07:05:57

+0

@ 0xc0de我終於寫了答案。 – galeksandrp 2018-01-16 08:27:17

0

獲取數據形成使用本地代理通過外部網站通過jherax你可以創建一個相應的外部URL獲取的內容爲你的PHP網頁的建議,比發獲取該頁面的請求。

var req = new XMLHttpRequest(); 
req.open('GET', 'http://localhost/get_url_content.php',false); 
if(req.status == 200) { 
    alert(req.responseText); 
} 

爲PHP代理,則可以使用https://github.com/cowboy/php-simple-proxy

0

只是把這個在你的PHP頁面,它帶病上班的頭沒有API:

header('Access-Control-Allow-Origin: *'); //allow everybody 

header('Access-Control-Allow-Origin: http://codesheet.org'); //allow just one domain 

$http_origin = $_SERVER['HTTP_ORIGIN']; //allow multiple domains 

$allowed_domains = array(
    'http://codesheet.org', 
    'http://stackoverflow.com' 
); 

if (in_array($http_origin, $allowed_domains)) 
{ 
    header("Access-Control-Allow-Origin: $http_origin"); 
}