ajax跨域之服务端代理
事件背景:
某系统A(A.com)对外提供一个邮件发送接口,可接收GET或POST方式传递参数(如email, subject, body等)数据。当某小系统b(b.com)需要使用到这个接口的功能时,并提供比较好的用户体验时,采取了通过ajax将用户填入的信息传递数据给这个接口,来实现发送邮件的目的。
问题在于:某系统A和某小系统b分属于两个域名下,在物理和逻辑上都是互相独立和分离的,将无法发起ajax连接,IE下显示为无权限。
思路分析:
无法进行ajax连接,是因为浏览器安全模型的同源策略,存在跨域问题。
同源策略阻止从一个源加载的文档或脚本获取或设置另一个源加载的文档的属性。A.com和b.com分属于不同的源,因此不能通过js互相访问。
从最简单的方法来说,使其从同一个源(表现为同一访问协议、同一端口和同一域名下)获取数据不就符合同源策略了?
为了实现从同一源获取,我们在b.com的源上设置一个代理,通过这个代理传递数据到A.com,这个代理负责和A.com进行通信,这在服务器端是很容易实现的。
解决方案:
1. 在某小系统b的页面中,ajax(使用jQuery)请求代理,传递参数:
$.post(
'http://b.com/proxy.php', // 代理程序地址
{
email:"impng@impng.com",
subject:"ajax跨域之代理",
body:"这里是邮件内容"
},
function(data){
if(data == 1) alert('发送成功!');
}
);
2. 某小系统b的代理程序(proxy.php),复杂向某系统A传递数据:
$post = $_POST; // 简单接收客户端传递来的参数
$data = array(
'email' => $post['email'],
'subject' => $post['subject'],
'body' => $post['body'],
);
$url = 'http://A.com/ISendMail.php?'; // 某系统A的发送邮件接口
$url .= http_build_query($data); // 传递从某小系统b传递来的数据
$rt = file_get_contents($url);
echo $rt;
总结:
将无法进行跨域访问的ajax请求转化为同域,由代理进行跨域,绕过了浏览器的安全模型,简单解决了ajax的跨域问题。但这样的方式需要一个代理程序,不能单使用js解决。在这篇文章《ajax跨域之JSONP》中介绍了一种直接通过js实现跨域的方法。