在做项目的时候,客户要做成客户端和服务端两部分,客户端向服务端进行认证,我开始的时候没有直接替换ip地址,后来采用ip地址替换之后,出现了问题,后台可以收到访问的请求,但是无法拿到后台返回的信息,后来咨询了些大牛才知道是js中限制跨域访问的,也就是说,你的js中有些数据不能直接通过A服务器拿到B服务器的数据。
域(Domain)是Windows网络中独立运行的单位,域之间相互访问则需要建立信任关系(即Trust Relation)。信任关系是连接在域与域之间的桥梁。当一个域与其他域建立了信任关系后,2个域之间不但可以按需要相互进行管理,还可以跨网分配文件和打印机等设备资源,使不同的域之间实现网络资源的共享与管理。 有一种简明的说法来解释广域跨域:跨域访问,简单来说就是 A 网站的 javascript 代码试图访问 B 网站,包括提交内容和获取内容。由于安全原因,跨域访问是被各大浏览器所默认禁止的。
由于浏览器实现的同源策略的限制,XmlHttpRequest只允许请求当前源(域名、协议、端口)的资源,所以AJAX是不允许跨域的。不过像<script>,<link>,<img>,<iframe>这些标签是允许跨域的,但你并不能修改这些资源,比如iframe里的内容。
为什么浏览器要实现同源限制?我们举例说明:
比如一个黑客,他利用iframe把真正的银行登录页面嵌到他的页面上,当你使用真实的用户名和密码登录时,如果没有同源限制,他的页面就可以通过JavaScript读取到你的表单中输入的内容,这样用户名和密码就轻松到手了.又比如你登录了OSC,同时浏览了恶意网站,如果没有同源限制,该恶意网站就可以构造AJAX请求频繁在OSC发广告帖.---出处
解决方案:
1、 通过后台解决跨域问题:js向服务器发送请求,然后让服务器去另一个域上获取数据后返回。该方式我是比较喜欢的,需要自己写http请求,去请求另一个域的服务器的数据,然后将得到的数据提交给前台。2、 在前端解决跨域问题:用JSONP。
下面是对于前端解决跨域问题的一个小实例,留作后面遇到同样问题的一个参考或者是遇到这个问题的其他的朋友希望也能帮到你。
这里的URL地址可以直接替换为你想访问的服务器的路径。
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'index.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<script type="text/javascript" src="js/jquery-1.8.0.js"></script>
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
<script type="text/javascript">
$(function(){
/*
//简写形式,效果相同
$.getJSON("< %=basePath%>TestServlet?sid=1494&busiId=101&jsonpCallback=?",
function(data){
$("#showcontent").text("Result:"+data.result)
});
*/
$.ajax({
type : "get",
async:false,
url : "<%=basePath%>TestServlet?sid=1494&busiId=101",
dataType : "jsonp",//数据类型为jsonp
jsonp: "jsonpCallback",//服务端用于接收callback调用的function名的参数
success : function(data){
$("#showcontent").text("Result:"+data.result)
},
error:function(){
alert('fail');
}
});
});
</script>
</head>
<body>
<div id="showcontent">Result:</div>
</body>
</html>
后台采用Servlet的形式,返回的数据需要定义好格式,jsonCallback+"({"result":"result"})",其中jsonCallback是前台传过来的参数。
public class TestServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
try{
response.setContentType("text/plain");
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setDateHeader("Expires", 0);
Map<String,String> map = new HashMap<String,String>();
map.put("result", "content");
PrintWriter out = response.getWriter();
JSONObject resultJSON = JSONObject.fromObject(map); //根据需要拼装json
String jsonpCallback = request.getParameter("jsonpCallback");//客户端请求参数
out.println(jsonpCallback+"("+resultJSON.toString(1,1)+")");//返回jsonp格式数据
out.flush();
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}