简体   繁体   English

使用 AJAX 加载跨域端点

[英]Loading cross-domain endpoint with AJAX

I'm trying to load a cross-domain HTML page using AJAX but unless the dataType is "jsonp" I can't get a response.我正在尝试使用 AJAX 加载跨域 HTML 页面,但除非数据类型为“jsonp”,否则我无法获得响应。 However using jsonp the browser is expecting a script mime type but is receiving "text/html".然而,使用 jsonp 浏览器需要一个脚本 mime 类型,但接收“text/html”。

My code for the request is:我的请求代码是:

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

Is there any way of avoiding using jsonp for the request?有什么办法可以避免在请求中使用 jsonp 吗? I've already tried using the crossDomain parameter but it didn't work.我已经尝试过使用 crossDomain 参数,但是没有用。

If not is there any way of receiving the html content in jsonp?如果没有,有没有办法在 jsonp 中接收 html 内容? Currently the console is saying "unexpected <" in the jsonp reply.目前,控制台在 jsonp 回复中说“意外 <”。

jQuery Ajax Notes jQuery Ajax 注释

  • Due to browser security restrictions, most Ajax requests are subject to the same origin policy ;由于浏览器安全限制,大多数Ajax请求都遵循同源策略 the request can not successfully retrieve data from a different domain, subdomain, port, or protocol.请求无法从不同的域、子域、端口或协议成功检索数据。
  • Script and JSONP requests are not subject to the same origin policy restrictions.脚本和 JSONP 请求不受同源策略限制。

There are some ways to overcome the cross-domain barrier:有一些方法可以克服跨域障碍:

There are some plugins that help with cross-domain requests:有一些插件可以帮助处理跨域请求:

Heads up!当心!

The best way to overcome this problem, is by creating your own proxy in the back-end, so that your proxy will point to the services in other domains, because in the back-end not exists the same origin policy restriction.解决这个问题的最好方法是在后端创建自己的代理,这样您的代理将指向其他域中的服务,因为在后端不存在同源策略限制。 But if you can't do that in back-end, then pay attention to the following tips.但是如果你在后端不能这样做,那么请注意以下提示。


**Warning!** **警告!**

Using third-party proxies is not a secure practice, because they can keep track of your data, so it can be used with public information, but never with private data.使用第三方代理并不是一种安全的做法,因为它们可以跟踪您的数据,因此它可以用于公共信息,但绝不能用于私人数据。


The code examples shown below use jQuery.get() and jQuery.getJSON() , both are shorthand methods of jQuery.ajax()下面显示的代码示例使用jQuery.get()jQuery.getJSON() ,两者都是jQuery.ajax() 的速记方法


CORS Anywhere任何地方的 CORS

2021 Update 2021 更新

Public demo server (cors-anywhere.herokuapp.com) will be very limited by January 2021, 31st公共演示服务器 (cors-anywhere.herokuapp.com) 将在 2021 年 1 月 31 日非常有限

The demo server of CORS Anywhere (cors-anywhere.herokuapp.com) is meant to be a demo of this project. CORS Anywhere (cors-anywhere.herokuapp.com) 的演示服务器旨在作为该项目的演示。 But abuse has become so common that the platform where the demo is hosted (Heroku) has asked me to shut down the server, despite efforts to counter the abuse.但是滥用已经变得如此普遍,以至于托管演示的平台 (Heroku) 要求我关闭服务器,尽管努力打击滥用。 Downtime becomes increasingly frequent due to abuse and its popularity.由于滥用及其流行,停机时间变得越来越频繁。

To counter this, I will make the following changes:为了解决这个问题,我将进行以下更改:

  1. The rate limit will decrease from 200 per hour to 50 per hour.速率限制将从每小时 200 次降至每小时 50 次。
  2. By January 31st, 2021, cors-anywhere.herokuapp.com will stop serving as an open proxy.到 2021 年 1 月 31 日,cors-anywhere.herokuapp.com 将停止作为开放代理服务。
  3. From February 1st.从 2 月 1 日起。 2021, cors-anywhere.herokuapp.com will only serve requests after the visitor has completed a challenge: The user (developer) must visit a page at cors-anywhere.herokuapp.com to temporarily unlock the demo for their browser. 2021 年,cors-anywhere.herokuapp.com 将仅在访问者完成挑战后才提供请求:用户(开发者)必须访问 cors-anywhere.herokuapp.com 上的页面以临时解锁其浏览器的演示。 This allows developers to try out the functionality, to help with deciding on self-hosting or looking for alternatives.这允许开发人员试用该功能,以帮助决定自托管或寻找替代方案。

CORS Anywhere is a node.js proxy which adds CORS headers to the proxied request. CORS Anywhere 是一个node.js 代理,它将 CORS 标头添加到代理请求中。
To use the API, just prefix the URL with the API URL.要使用 API,只需在 URL 前面加上 API URL。 (Supports https : see github repository ) (支持https :见github 仓库

If you want to automatically enable cross-domain requests when needed, use the following snippet:如果您想在需要时自动启用跨域请求,请使用以下代码段:

 $.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无论起源

Whatever Origin is a cross domain jsonp access.无论Origin跨域jsonp访问。 This is an open source alternative to anyorigin.com .这是anyorigin.com 的开源替代

To fetch the data from google.com, you can use this snippet:要从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 Proxy CORS 代理

CORS Proxy is a simple node.js proxy to enable CORS request for any website. CORS 代理是一个简单的node.js 代理,用于为任何网站启用 CORS 请求。 It allows javascript code on your site to access resources on other domains that would normally be blocked due to the same-origin policy.它允许您站点上的 javascript 代码访问其他域上的资源,这些域通常由于同源策略而被阻止。

How does it work?它是如何工作的? CORS Proxy takes advantage of Cross-Origin Resource Sharing, which is a feature that was added along with HTML 5. Servers can specify that they want browsers to allow other websites to request resources they host. CORS 代理利用跨源资源共享,这是与 HTML 5 一起添加的一项功能。服务器可以指定他们希望浏览器允许其他网站请求他们托管的资源。 CORS Proxy is simply an HTTP Proxy that adds a header to responses saying "anyone can request this". CORS 代理只是一个 HTTP 代理,它向响应添加一个标头,说“任何人都可以请求这个”。

This is another way to achieve the goal (see www.corsproxy.com ).这是实现目标的另一种方式(参见www.corsproxy.com )。 All you have to do is strip http:// and www.您所要做的就是去掉http://www。 from the URL being proxied, and prepend the URL with www.corsproxy.com/来自被代理的 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 proxy browser CORS 代理浏览器

Recently I found this one, it involves various security oriented Cross Origin Remote Sharing utilities.最近我发现了这个,它涉及各种面向安全的跨域远程共享实用程序。 But it is a black-box with Flash as backend.但它是一个以 Flash 作为后端的黑匣子。

You can see it in action here: CORS proxy browser您可以在这里看到它的实际效果: CORS 代理浏览器
Get the source code on GitHub: koto/cors-proxy-browser在 GitHub 上获取源代码: koto/cors-proxy-browser

You can use Ajax-cross-origin a jQuery plugin.您可以使用 Ajax-cross-origin 一个 jQuery 插件。 With this plugin you use jQuery.ajax() cross domain.使用此插件,您可以使用jQuery.ajax()跨域。 It uses Google services to achieve this:它使用 Google 服务来实现这一点:

The AJAX Cross Origin plugin use Google Apps Script as a proxy jSON getter where jSONP is not implemented. AJAX Cross Origin 插件使用 Google Apps Script 作为代理 jSON getter,其中未实现 jSONP。 When you set the crossOrigin option to true, the plugin replace the original url with the Google Apps Script address and send it as encoded url parameter.当您将 crossOrigin 选项设置为 true 时,插件会用 Google Apps 脚本地址替换原始 url,并将其作为编码的 url 参数发送。 The Google Apps Script use Google Servers resources to get the remote data, and return it back to the client as JSONP. Google Apps Script 使用 Google Servers 资源获取远程数据,并将其作为 JSONP 返回给客户端。

It is very simple to use:使用非常简单:

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

You can read more here: http://www.ajax-cross-origin.com/您可以在此处阅读更多信息: http : //www.ajax-cross-origin.com/

If the external site doesn't support JSONP or CORS, your only option is to use a proxy.如果外部站点不支持 JSONP 或 CORS,您唯一的选择是使用代理。

Build a script on your server that requests that content, then use jQuery ajax to hit the script on your server.在您的服务器上构建一个请求该内容的脚本,然后使用 jQuery ajax 在您的服务器上运行该脚本。

Just put this in the header of your PHP Page and it ill work without API:只要把它放在你的 PHP 页面的标题中,它就不会在没有 API 的情况下工作:

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

or或者

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

or或者

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

I'm posting this in case someone faces the same problem I am facing right now.我发布这个以防有人面临我现在面临的同样问题。 I've got a Zebra thermal printer, equipped with the ZebraNet print server, which offers a HTML-based user interface for editing multiple settings, seeing the printer's current status, etc. I need to get the status of the printer, which is displayed in one of those html pages, offered by the ZebraNet server and, for example, alert() a message to the user in the browser.我有一台 Zebra 热敏打印机,配备了 ZebraNet 打印服务器,它提供基于 HTML 的用户界面,用于编辑多个设置、查看打印机的当前状态等。我需要获取打印机的状态,该状态显示在其中一个 html 页面中,由 ZebraNet 服务器提供,例如,alert() 向浏览器中的用户发送消息。 This means that I have to get that html page in Javascript first.这意味着我必须首先在 Javascript 中获取该 html 页面。 Although the printer is within the LAN of the user's PC, that Same Origin Policy is still staying firmly in my way.尽管打印机位于用户 PC 的 LAN 内,但同源策略仍然牢牢地挡住了我的路。 I tried JSONP, but the server returns html and I haven't found a way to modify its functionality (if I could, I would have already set the magic header Access-control-allow-origin: *).我尝试了 JSONP,但服务器返回 html,我还没有找到修改其功能的方法(如果可以,我已经设置了魔术头 Access-control-allow-origin:*)。 So I decided to write a small console app in C#.所以我决定用 C# 编写一个小的控制台应用程序。 It has to be run as Admin to work properly, otherwise it trolls :D an exception.它必须以管理员身份运行才能正常工作,否则它会引发 :D 异常。 Here is some code:这是一些代码:

// 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();

All the user needs to do is run that console app as Admin.用户所需要做的就是以管理员身份运行该控制台应用程序。 I know it is way too ... frustrating and complicated, but it is sort of a workaround to the Domain Policy problem in case you cannot modify the server in any way.我知道这太……令人沮丧和复杂,但它是域策略问题的一种解决方法,以防您无法以任何方式修改服务器。

edit: from js I make a simple ajax call:编辑:从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);
                }
            });

The html of the requested page is returned and stored in the data variable.请求页面的 html 被返回并存储在data变量中。

To get the data form external site by passing using a local proxy as suggested by jherax you can create a php page that fetches the content for you from respective external url and than send a get request to that php page.要通过使用 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);
}

as a php proxy you can use https://github.com/cowboy/php-simple-proxy作为 php 代理,您可以使用https://github.com/cowboy/php-simple-proxy

Your URL doesn't work these days, but your code can be updated with this working solution:这些天您的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>

You need CORS proxy which proxies your request from your browser to requested service with appropriate CORS headers .您需要 CORS 代理,它将您的请求从您的浏览器代理到具有适当CORS 标头的请求服务。 List of such services are in code snippet below.此类服务的列表在下面的代码片段中。 You can also run provided code snippet to see ping to such services from your location.您还可以运行提供的代码片段以查看从您所在位置对此类服务的 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>

Figured it out.弄清楚了。 Used this instead.用这个代替。

$('.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