用 AJAX 加载跨域端点

我正在尝试使用 AJAX 加载跨域 HTML 页面,但是除非 dataType 是“ 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 处理请求吗?我已经尝试使用 cross Domain 参数,但是它不起作用。

如果没有任何方法接收 jsonp 中的 html 内容?目前,控制台在 jsonp 回复中显示为“始料未及 <”。

301678 次浏览

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

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

JQuery Ajax 注释

  • 由于浏览器的安全限制,大多数 阿贾克斯请求都服从于 同一原产地政策; 请求不能成功地从不同的域、子域、端口或协议检索数据。
  • 脚本和 JSONP 请求不受相同的源策略限制。

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

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

小心!

克服这个问题的最佳方法是在后端创建您自己的代理,这样您的代理将指向其他域中的服务,因为在后端不存在 同一原产地政策限制。但是,如果在后端不能做到这一点,那么请注意以下提示。


警告

使用第三方代理并不是一种安全的做法,因为它们可以跟踪您的数据,因此可以将其用于公共信息,但用于私有数据的 永远不会


下面显示的代码示例使用 一个 href = “ http://api.jquery.com/jQuery.get/”rel = “ nofollow norefrer”> jQuery. get () JQuery.getJSON () ,它们都是 JQuery.ajax () 的简写方法


任何地方

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 是什么,它都是一个 跨域交互作用访问。

要从 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)。您所要做的就是从被代理的 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);
});


http://www.corsproxy.com/域现在看起来是一个不安全/可疑的站点。不推荐使用。


CORS 代理浏览器

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

你可以在这里看到它的作用: CORS 代理浏览器
在 GitHub 上获取源代码:

您可以使用 Ajax 交叉原点的 jQuery 插件。 使用这个插件,你可以使用 jQuery.ajax()跨域名。它使用谷歌服务来实现这一点:

AJAX Cross Origin 插件使用 Google Apps Script 作为代理 jSON 在 jSONP 没有实现的地方设置 getter 选项为 true 时,插件用 Google 替换原来的 URL 应用程序脚本地址,并将其作为编码的 url 参数发送 AppsScript 使用 GoogleServers 资源获取远程数据,并且 将其作为 JSONP 返回给客户机。

它的使用非常简单:

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

你可在此浏览更多资料: Http://www.ajax-cross-origin.com/

我想明白了。 用这个代替。

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

我发布这个是为了防止有人遇到和我现在一样的问题。我有一台 Zebra 热敏打印机,配备了 ZebraNet 打印服务器,它提供了一个基于 HTML 的用户界面,用于编辑多个设置,查看打印机的当前状态等。我需要获得打印机的状态,这个状态显示在 ZebraNet 服务器提供的 html 页面中,并且,例如,在浏览器中向用户发送一条消息。这意味着我必须首先在 Javascript 中获得 html 页面。虽然打印机是在用户的电脑局域网内,该 同一原产地政策仍然坚定地留在我的方式。我尝试了 JSONP,但是服务器返回 html,我还没有找到修改其功能的方法(如果可以的话,我已经设置了神奇的头部 Access-control-allow-source: *)。所以我决定用 C # 编写一个小的控制台应用程序。它必须以管理员的身份运行才能正常工作,否则就会出现异常。下面是一些代码:

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

所有用户需要做的就是以管理员身份运行控制台应用程序。我知道这太... ... 令人沮丧和复杂了,但是如果您不能以任何方式修改服务器,这是解决域策略问题的一种方法。

我做了一个简单的 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 并将其存储在 资料变量中。

您需要 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>

要通过使用 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

只要把这个放在你的 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");
}

你的 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>