繁体   English   中英

使用 AJAX 加载跨域端点

[英]Loading cross-domain endpoint with AJAX

我正在尝试使用 AJAX 加载跨域 HTML 页面,但除非数据类型为“jsonp”,否则我无法获得响应。 然而,使用 jsonp 浏览器需要一个脚本 mime 类型,但接收“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 回复中说“意外 <”。

jQuery Ajax 注释

  • 由于浏览器安全限制,大多数Ajax请求都遵循同源策略 请求无法从不同的域、子域、端口或协议成功检索数据。
  • 脚本和 JSONP 请求不受同源策略限制。

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

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

当心!

解决这个问题的最好方法是在后端创建自己的代理,这样您的代理将指向其他域中的服务,因为在后端不存在同源策略限制。 但是如果你在后端不能这样做,那么请注意以下提示。


**警告!**

使用第三方代理并不是一种安全的做法,因为它们可以跟踪您的数据,因此它可以用于公共信息,但绝不能用于私人数据。


下面显示的代码示例使用jQuery.get()jQuery.getJSON() ,两者都是jQuery.ajax() 的速记方法


任何地方的 CORS

2021 更新

公共演示服务器 (cors-anywhere.herokuapp.com) 将在 2021 年 1 月 31 日非常有限

CORS Anywhere (cors-anywhere.herokuapp.com) 的演示服务器旨在作为该项目的演示。 但是滥用已经变得如此普遍,以至于托管演示的平台 (Heroku) 要求我关闭服务器,尽管努力打击滥用。 由于滥用及其流行,停机时间变得越来越频繁。

为了解决这个问题,我将进行以下更改:

  1. 速率限制将从每小时 200 次降至每小时 50 次。
  2. 到 2021 年 1 月 31 日,cors-anywhere.herokuapp.com 将停止作为开放代理服务。
  3. 从 2 月 1 日起。 2021 年,cors-anywhere.herokuapp.com 将仅在访问者完成挑战后才提供请求:用户(开发者)必须访问 cors-anywhere.herokuapp.com 上的页面以临时解锁其浏览器的演示。 这允许开发人员试用该功能,以帮助决定自托管或寻找替代方案。

CORS Anywhere 是一个node.js 代理,它将 CORS 标头添加到代理请求中。
要使用 API,只需在 URL 前面加上 API URL。 (支持https :见github 仓库

如果您想在需要时自动启用跨域请求,请使用以下代码段:

 $.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); });

无论起源

无论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 代理只是一个 HTTP 代理,它向响应添加一个标头,说“任何人都可以请求这个”。

这是实现目标的另一种方式(参见www.corsproxy.com )。 您所要做的就是去掉http://www。 来自被代理的 URL,并在 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 代理浏览器
在 GitHub 上获取源代码: koto/cors-proxy-browser

您可以使用 Ajax-cross-origin 一个 jQuery 插件。 使用此插件,您可以使用jQuery.ajax()跨域。 它使用 Google 服务来实现这一点:

AJAX Cross Origin 插件使用 Google Apps Script 作为代理 jSON getter,其中未实现 jSONP。 当您将 crossOrigin 选项设置为 true 时,插件会用 Google Apps 脚本地址替换原始 url,并将其作为编码的 url 参数发送。 Google Apps Script 使用 Google Servers 资源获取远程数据,并将其作为 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");
}

我发布这个以防有人面临我现在面临的同样问题。 我有一台 Zebra 热敏打印机,配备了 ZebraNet 打印服务器,它提供基于 HTML 的用户界面,用于编辑多个设置、查看打印机的当前状态等。我需要获取打印机的状态,该状态显示在其中一个 html 页面中,由 ZebraNet 服务器提供,例如,alert() 向浏览器中的用户发送消息。 这意味着我必须首先在 Javascript 中获取该 html 页面。 尽管打印机位于用户 PC 的 LAN 内,但同源策略仍然牢牢地挡住了我的路。 我尝试了 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 被返回并存储在data变量中。

要通过使用 jherax 建议的本地代理传递来获取外部站点的数据,您可以创建一个 php 页面,从相应的外部 url 为您获取内容,然后向该 php 页面发送 get 请求。

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 标头的请求服务。 此类服务的列表在下面的代码片段中。 您还可以运行提供的代码片段以查看从您所在位置对此类服务的 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');

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM