使用带有 Jquery 跨域问题的 DHIS 2 API
Posted
技术标签:
【中文标题】使用带有 Jquery 跨域问题的 DHIS 2 API【英文标题】:Using DHIS 2 API With Jquery Cross domain issue 【发布时间】:2014-09-27 09:38:10 【问题描述】:我正在尝试实现一个使用 DHIS 2 API 的 javascript 应用程序。我花了一整天的时间尝试使用 Jquery 进行身份验证。
API 说 (https://www.dhis2.org/doc/snapshot/en/user/html/ch32s02.html) 您需要使用 base 64 身份验证。我试图在 Jquery 中实现它,但我遇到了跨域问题。我曾尝试使用 DHIS 2 演示 (https://apps.dhis2.org/dev/) 进行身份验证,但未成功。然后我在本地计算机上设置了一个本地副本,但我仍然遇到与 DHIS 2 在不同端口上运行相同的问题。
我尝试过 jsonp 和 CROS,但没有成功。
这是我目前正在尝试的代码
$(function()
var base_url = "http://apps.dhis2.org/demo/";
var login = 'dhis-web-commons-security/login.action?authOnly=true';
var current_user_url = 'api/users.json';
var params =
'j_username':'admin',
'j_password':'district'
;
function base_64_auth(user,password)
var tok = user + ':' + password;
var hash = Base64.encode(tok);
return "Basic " + hash;
var auth = base_64_auth('admin','district');
$.ajax(
url : base_url+login,
data : params,
type : 'POST',
dataType : 'text',
crossDomain : true,
xhrFields :
'withCredentials':true
,
beforeSend : function(req)
req.setRequestHeader('Authorization',auth);
,
success : function(data)
console.log('authentification succeded');
alert('success');
//userInfo();
,error : function(xhr,type,msg)
console.log(xhr.responseText);
console.log(type);
console.log(msg);
);
);
我正在使用一个简单的库进行 base64 编码 www.webtoolkit.info/javascript-base64.html#.U9_O2XVdWkA
检查控制台我看到这个错误:
XMLHttpRequest 无法加载 http://apps.dhis2.org/demo/dhis-web-commons-security/login.action?authOnly=true
。请求被重定向到'http://apps.dhis2.org/demo/dhis-web-commons/security/login.action?failed=true'
,这对于需要预检的跨域请求是不允许的。
如果有人曾经使用过 API,我会很感激他的帮助,或者如果你知道任何其他方式(包括其他语言)我可能能够与 API 交谈,我可能会去。
非常感谢。
【问题讨论】:
【参考方案1】:跨域请求通常会被浏览器阻止。我自己在一个小组项目中使用 DHIS2 API,我们通过在 chrome 中禁用同源策略来解决这个问题,方法是运行:
google-chrome --disable-web-security
请注意,您仍然需要验证对演示服务器的请求,并且此解决方案无论如何都不理想。我猜最好的方法是在本地部署服务器并将所有文件放在服务器上,以便请求发生在与服务器相同的域上。另请注意,在 chrome 中禁用网络安全时,最好使用其他浏览器来处理邮件、facebook 等。
【讨论】:
【参考方案2】:DHIS 2.18 版有一个启用 CORS 的选项。可以在系统设置 -> 远程访问
中列出应该允许 CORS 访问的域https://www.dhis2.org/218
【讨论】:
【参考方案3】:试试下面的php代码:
$post_string_b64 = base64_encode("user:password");
$auth = 'Authorization: Basic '.$post_string_b64;
$ch = curl_init("dhis2server/api/dataSets?paging=false");
curl_setopt($ch, CURLOPT_HTTPHEADER, array($auth));
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FRESH_CONNECT, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
$html = curl_exec($ch);
然后您会得到一个 json 响应,您可以通过以下方式使其可读:
$pattern = '/\(.+)\/';
preg_match($pattern, $html, $matches);
$json = json_decode($matches[0], true);
代码应该是不言自明的,但有什么不清楚的地方可以随时提问,
问候
【讨论】:
【参考方案4】:在 2.18 版中,DHIS 2 增加了对 CORS 的支持,允许跨不同来源/域共享资源。
您可以设置一个域名白名单,您的 DHIS 2 实例将接受来自应用程序 > 设置 > 访问下的请求。换句话说,您必须在 DHIS 2 中定义您计划从中请求 DHIS 2 数据的域。因此,如果您计划在 webportal.org 上设置一个从 DHIS 2 检索数据的 Web 门户,那么您必须将 webportal.org 定义为列入白名单的 CORS 域。
Docs here
【讨论】:
【参考方案5】:@Ajmal A 我可以确认在 系统设置 -> 访问 -> CORS 白名单 中编辑适当的 CORS 设置是有效的。我们使用的是 DHIS2 2.25 版。
我现在正在localhost:3000
上处理我们的客户端应用程序,在列入白名单后,我现在可以使用以下 jQuery AJAX 调用来获取数据。
var apiUrl = "https://<YOUR_URL>/api/<YOUR_RESOURCE>?format=json";
$.ajax(
url: apiUrl,
type: "GET",
crossDomain: true,
xhrFields :
'withCredentials':true
,
dataType : "json",
username: "<YOUR_USERNAME>",
password: "<YOUR_PASSWORD>"
)
.done(function( json )
console.log(json);
)
.fail(function( xhr, status, errorThrown )
console.log( "AJAX request failed on " + apiUrl );
console.log( "Error: " + errorThrown );
console.log( "Status: " + status );
console.dir( xhr );
)
.always(function( xhr, status )
console.log( "AJAX request closed." );
);
【讨论】:
【参考方案6】:您无法从外部 DHIS 平台(即不同的域)访问。 DHIS 不允许这样做。 我也花了两天时间。然后,DHIS 志愿者告诉了我。
【讨论】:
感谢您的回答。我最终使用 Java 而不是 Javascript 调用 API。现在可以正常使用了以上是关于使用带有 Jquery 跨域问题的 DHIS 2 API的主要内容,如果未能解决你的问题,请参考以下文章
由于跨域请求,带有 Jquery 文件上传的 Carrierwave_Direct 不会重定向