使用AJAX加载跨域端点

问题描述 投票:131回答:9

我正在尝试使用AJAX加载跨域HTML页面,但除非dataType为“ jsonp”,否则无法获得响应。但是,使用jsonp时,浏览器期望使用脚本哑剧类型,但接收到“ text / html”。

我的请求代码是:

$.ajax({
    type: "GET",
    url: "http://saskatchewan.univ-ubs.fr:8080/SASStoredProcess/do?_username=DARTIES3-2012&_password=P@ssw0rd&_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回复中说“意外

javascript jquery ajax cross-domain
9个回答
232
投票

jQuery Ajax注释

  • 由于浏览器安全性的限制,大多数Ajax请求均受same origin policy的约束;该请求无法从其他域,子域,端口或协议成功检索数据。
  • 脚本和JSONP请求不受相同的原始策略限制。

有一些方法可以克服跨域障碍:

有些插件可以帮助处理[[跨域请求:

  • 抬起头!

  • 解决此问题的最佳方法是,在后端创建您自己的代理,这样您的代理将指向其他域中的服务,因为在后端不存在

    相同来源策略] >限制。但是,如果您不能在后端执行此操作,请注意以下提示。


    警告!使用第三方代理不是安全的做法,因为它们可以跟踪您的数据,因此可以与公共信息一起使用,但

    从不

    与私有数据一起使用。


    下面显示的代码示例使用jQuery.get()jQuery.getJSON(),它们都是jQuery.ajax()
    的简写方法


    CORS Anywhere

    CORS Anywhere是

    node.js代理]],它将CORS标头添加到代理请求中。要使用API​​,只需在URL前面加上API 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 Proxy利用了跨域资源共享功能,该功能是随HTML 5一起添加的。服务器可以指定它们希望浏览器允许其他网站请求其托管的资源。 CORS代理只是一个HTTP代理,它在响应中添加一个标头,说“任何人都可以请求此信息”。
  • 这是实现目标的另一种方法(请参见www.corsproxy.com)。您所要做的就是从要代理的URL中删除

    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代理浏览器

    最近,我发现了这个,它涉及各种面向安全性的跨源远程共享实用程序。但这是一个以Flash为后端的黑匣子。

    您可以在此处查看它的运行情况:CORS proxy browser在GitHub上获取源代码:koto/cors-proxy-browser

    您可以使用Ajax跨源jQuery插件。通过此插件,您可以使用jQuery.ajax()跨域。它使用Google服务来实现这一目标:

    AJAX Cross Origin插件使用Google Apps脚本作为代理jSON尚未实现jSONP的getter。设置crossOrigin时选项设置为true,则插件将原始网址替换为GoogleApps脚本地址,并将其作为编码的url参数发送。谷歌Apps脚本使用Google服务器资源来获取远程数据,并且以JSONP的形式返回给客户端。

    使用非常简单:

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

    您可以在这里阅读更多内容:http://www.ajax-cross-origin.com/

    如果外部站点不支持JSONP或CORS,则您唯一的选择是使用代理。

    在服务器上构建一个请求该内容的脚本,然后使用jQuery ajax在服务器上命中该脚本。

    只需将其放在您的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"); }

    [如果有人遇到我现在面临的相同问题,我会发布此信息。我有一台配备ZebraNet打印服务器的Zebra热敏打印机,该服务器提供基于HTML的用户界面,用于编辑多个设置,查看打印机的当前状态等。我需要获取打印机的状态,该状态会显示在ZebraNet服务器提供的这些html页面之一中,例如,alert()向浏览器中的用户发送一条消息。这意味着我必须先在Javascript中获取该html页面。尽管打印机位于用户PC的LAN内,但是Same Origin Policy仍然坚如磐石。我尝试了JSONP,但是服务器返回了html,但是我还没有找到修改其功能的方法(如果可以的话,我已经设置了魔术头Access-control-allow-origin:*)。因此,我决定用C#编写一个小型控制台应用程序。它必须以Admin身份运行才能正常工作,否则它将抛出: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返回并存储在

    data

    变量中。
    [按照jherax的建议,通过使用本地代理传递来获取外部网站的数据,您可以创建一个php页面,该页面从相应的外部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

    您的URL目前无法使用,但是可以使用此有效解决方案来更新您的代码:

    var url = "http://saskatchewan.univ-ubs.fr:8080/SASStoredProcess/do?_username=DARTIES3-2012&_password=P@ssw0rd&_program=%2FUtilisateurs%2FDARTIES3-2012%2FMon+dossier%2Fanalyse_dc&annee=2012&ind=V&_action=execute"; url = 'https://google.com'; // TEST URL $.get("https://images"+~~(Math.random()*33)+"-focus-opensocial.googleusercontent.com/gadgets/proxy?container=none&url=" + encodeURI(url), function(data) { $('div.ajax-field').html(data); });
    <div class="ajax-field"></div>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    您需要CORS代理,该代理可以使用适当的CORS headers代理从浏览器向请求的服务发送的请求。此类服务的列表在下面的代码段中。您还可以运行提供的代码段,以从您所在的位置查看对此类服务的ping。

    $('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>
    想通了。改用它。

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


    24
    投票
    您可以使用Ajax跨源jQuery插件。通过此插件,您可以使用jQuery.ajax()跨域。它使用Google服务来实现这一目标:

    AJAX Cross Origin插件使用Google Apps脚本作为代理jSON尚未实现jSONP的getter。设置crossOrigin时选项设置为true,则插件将原始网址替换为GoogleApps脚本地址,并将其作为编码的url参数发送。谷歌Apps脚本使用Google服务器资源来获取远程数据,并且以JSONP的形式返回给客户端。

    13
    投票
    如果外部站点不支持JSONP或CORS,则您唯一的选择是使用代理。

    在服务器上构建一个请求该内容的脚本,然后使用jQuery ajax在服务器上命中该脚本。


    4
    投票
    只需将其放在您的PHP页面的标题中,并且在没有API的情况下就无法使用:

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


    0
    投票
    [如果有人遇到我现在面临的相同问题,我会发布此信息。我有一台配备ZebraNet打印服务器的Zebra热敏打印机,该服务器提供基于HTML的用户界面,用于编辑多个设置,查看打印机的当前状态等。我需要获取打印机的状态,该状态会显示在ZebraNet服务器提供的这些html页面之一中,例如,alert()向浏览器中的用户发送一条消息。这意味着我必须先在Javascript中获取该html页面。尽管打印机位于用户PC的LAN内,但是Same Origin Policy仍然坚如磐石。我尝试了JSONP,但是服务器返回了html,但是我还没有找到修改其功能的方法(如果可以的话,我已经设置了魔术头Access-control-allow-origin:*)。因此,我决定用C#编写一个小型控制台应用程序。它必须以Admin身份运行才能正常工作,否则它将抛出: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();


    0
    投票
    [按照jherax的建议,通过使用本地代理传递来获取外部网站的数据,您可以创建一个php页面,该页面从相应的外部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
    投票
    您的URL目前无法使用,但是可以使用此有效解决方案来更新您的代码:

    var url = "http://saskatchewan.univ-ubs.fr:8080/SASStoredProcess/do?_username=DARTIES3-2012&_password=P@ssw0rd&_program=%2FUtilisateurs%2FDARTIES3-2012%2FMon+dossier%2Fanalyse_dc&annee=2012&ind=V&_action=execute"; url = 'https://google.com'; // TEST URL $.get("https://images"+~~(Math.random()*33)+"-focus-opensocial.googleusercontent.com/gadgets/proxy?container=none&url=" + encodeURI(url), function(data) { $('div.ajax-field').html(data); });
    <div class="ajax-field"></div>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    您需要CORS代理,该代理可以使用适当的CORS headers代理从浏览器向请求的服务发送的请求。此类服务的列表在下面的代码段中。您还可以运行提供的代码段,以从您所在的位置查看对此类服务的ping。

    $('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>
    想通了。改用它。

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


    -2
    投票
    您需要CORS代理,该代理可以使用适当的CORS headers代理从浏览器向请求的服务发送的请求。此类服务的列表在下面的代码段中。您还可以运行提供的代码段,以从您所在的位置查看对此类服务的ping。

    -7
    投票
    想通了。改用它。
    © www.soinside.com 2019 - 2024. All rights reserved.