使用HTTP基本身份validation的JQuery Ajax调用
我有一个基于REST的服务器,我试图使用JQuery进行通信。 XML和JSON都可用作响应格式,因此我使用的是JSON。
连接都是SSL,因此HTTP基本身份validation是我们选择的授权方法,我们对其他前端没有任何问题(原始Javascript,Silverlight等…)
现在我试图将一些东西与JQuery放在一起,并使用HTTP基本身份validation遇到无穷无尽的问题。
我已经仔细研究了之前的许多问题,其中大部分都有解决方案似乎没有实际工作或将整个问题归咎于跨源访问,我已经在基本的Javascript测试中克服了这些问题。 响应始终将Request Access-Control-Allow-Origin
设置为请求中提供的Origin头,这可以在我的测试的响应中看到。
在基本的javascript中,这个完整的调用非常简单:
req.open('GET', 'https://researchdev-vm:8111/card', true, 'test', 'testpassword');
JQuery尝试这是相当标准的:
$.ajax({ username: 'test', password: 'testpassword', url: 'https://researchdev-vm:8111/card', type: 'GET', dataType: 'json', crossDomain: true, /*data: { username: 'test', password: 'testpassword' },*/ beforeSend: function(xhr){ xhr.setRequestHeader("Authorization", //"Basic " + encodeBase64(username + ":" + password)); "Basic AAAAAAAAAAAAAAAAAAA="); }, sucess: function(result) { out('done'); } });
实际上似乎提供身份validation的唯一方法是在beforeSend()
函数中直接插入Base64编码数据。 如果不包括在内,则无法取得任何进展。 用户名和密码属性似乎完全被忽略。
通过提供的beforeSend()
行为,GET调用获得包含数据的肯定响应。 但是,因为这是一个跨站点调用,所以OPTIONS调用在GET调用之前执行并且总是失败,因为它没有使用beforeSend()
,因此由于认证失败而获得401响应。
有没有更好的方法来完成应该是一个非常微不足道的电话? 如果OPTIONS请求没有使用beforeSend()
函数处理这一事实应该被视为错误吗? 有没有办法完全禁用OPTIONS检查? 不可能使这个调用不是跨站点,因为Javascript似乎甚至考虑与“跨站点”在同一台机器上的不同端口号。
这个问题可能已经过了它的’到期日期,但是我和Jquery一起工作时遇到了同样的问题。
用户名和密码属性似乎没有像通常完成HTTP基本身份validation那样对用户名/密码进行base64编码。
查看以下请求(简洁起见),首先使用JQuery AJAX方法中的“username”和“password”参数:
Request URL:http://testuser%40omnisoft.com:testuser@localhost:60023/Account Request Method:GET Accept:application/json, text/javascript, */*; q=0.01 Host:localhost:60023
现在使用beforeSend方法:
Request URL:http://localhost:60023/Account Request Method:GET Accept:application/json, text/javascript, */*; q=0.01 Authorization:Basic dXNlcm5hbWU6cGFzc3dvcmQ= Host:localhost:60023
请注意,第一种方法在请求中不包含“授权”标头,而是在目标URL前加上前缀。 我不是HTTP基本身份validation的专家,但它会表明前者不是一个正确的实现,因此失败(或者至少它与我自己的服务器实现有关)。
关于使用JSONP的OPTIONS请求 – 您可以尝试使用?callback=?
在您的url中而不是使用crossdomain
选项,只是为了明确。
这是一些充当AJAX调用的传递身份validation的东西。 这依赖于NTLM在javascript将执行的页面上进行身份validation。 也许这会对你有所帮助:
PHP代码:
var auth = " . $headers['Authorization'] . ""; unset($headers); ?>
使用jQuery你会这样使用它:
$.ajax({ type: 'POST', url: './somePage.php', data: {"test":true}, dataType: 'json', success: function(data) { console.log(data.username); }, beforeSend : function(req) { req.setRequestHeader('Authorization', auth); // <<<<----- USED HERE }, });
对于标准XMLHttpRequest:
var xml = new XMLHttpRequest(); xml.open('GET', './somePage.php', true); xml.setRequestHeader('Authorization', auth); // <<<<----- USED HERE xml.send();
对于遇到此问题的任何人,我已经解决了使用Apache拦截OPTIONS请求并仅将GET和POST转发到后端的问题。
此解决方案独立于appserver,因此也适用于PHP和Java:
# ServerName and other configuration... # CORS Header set Access-Control-Allow-Origin "*" Header set Access-Control-Allow-Methods "OPTIONS, GET, PUT, POST" Header set Access-Control-Allow-Headers "Authorization" # Intercept OPTIONS calls RewriteEngine On RewriteCond %{REQUEST_METHOD} ^(OPTIONS)$ RewriteRule .* - [L] # Backend, adapt this line to fit your needs RewriteRule /(.*) ajp://localhost:8010/$1 [L,P]
此致,毛里齐奥