先要说一下浏览器的“同源策略(SOP:Same Origin Policy)”。 简而言之,就是浏览器限制脚本程序只能和同协议、同域名、同端口的脚本进行交互,这包括共享和传递变量等。cookie的传递也是遵从同样策略。这就造成一些涉及到多个服务器的应用在整合时一些麻烦。跨域访问的问题造成A站点的Ajax代码无法访问B站点的数据。
Web页面上凡是拥有"src"这个属性的标签都拥有跨域的能力,比如<script>、<img>、<iframe>
浏览器判断是否跨域是根据地址栏的字符串判断的,而没有做DNS相应的转换,因此在地址栏中输入
http://localhost:8080/
http://hb.localhost:8080/
浏览器认为是两个域,而不会去判断是否是在同一个机器上面,所以
由于只有一台机器,只能在本机上模拟跨域的情况,因此在C:\WINDOWS\system32\drivers\etc目录下面的hosts文件中修改为
127.0.0.1 localhost 127.0.0.1 hb.localhost
意思是hb.localhost和localhost都代表127.0.0.1的地址
先展示一下自己写的jsonp 的例子
请求跨域的界面——访问的地址是:http://localhost:8080/myweb/jsonp/jsonpDemo.jsp
上面地址的域名是localhost:8080
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <Meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Insert title here</title> </head> <script type="text/javascript" src="../jquery-1.4.4.js"></script> <script type="text/javascript"> /* //直接获取当前工程下面的json.js文件 $.getJSON("json.js",function(json){ alert("JSON Data: " + json.name); }); //与上面的方法效果是一样的 $.getJSON("http://localhost:8080/myweb/jsonp/json.js",function(json){ alert("JSON Data: " + json.age); }); //由于发送请求的域是hb.localhost,与当前页面的不一致,jquery会提示无法访问,因为这样就已经跨域了,浏览器是不允许的。 $.getJSON("http://hb.localhost:8080/myweb/jsonp/json.js",function(json){ alert("JSON Data: " + json.age); }); */ function callback(json){ alert(json.name); } </script> <!-- <script type="text/javascript" src="http://hb.localhost:8080/myweb/jsonp/callback.js"></script> <script type="text/javascript" src="http://hb.localhost:8080/myweb/jsonp/callback.jsp?hb=callback"></script> --> <script type="text/javascript" src="http://hb.localhost:8080/myweb/JsonpDemo?hb=callback"></script> <body> </body> </html>
下面提供三种方式实现跨域(都是通过script标签引入的方式)
1、script标签引入JS文件(这个文件会运行当前域JS的方法,这个就是JSONP的原理)
callback({"name":"huangbiao"});
2、script标签引入JSP文件,处理逻辑之后生成JS文件
<% String callback = request.getParameter("hb"); System.out.println(callback); out.print(callback+"( { name:'John',age:'19'} );"); // out.print(callback); %>
备注:这个JSP页面不应该包含任何HTML标签,因为script引入的就是JS文件,否则页面会报错,无法正常解析
3、script标签引入URI,把请求交给servlet处理
package hb.jsonp; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class JsonpDemo extends HttpServlet { private static final long serialVersionUID = 1L; protected void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException { this.doPost(request,response); } protected void doPost(HttpServletRequest request,IOException { System.out.println("————————————doPost————————————"); String callback = request.getParameter("hb"); response.setContentType("text/plain"); response.setHeader("Pragma","No-cache"); response.setHeader("Cache-Control","no-cache"); response.setDateHeader("Expires",0); PrintWriter pw = response.getWriter(); System.out.println(callback + "({'name':'huangbiao','age':'11'});"); pw.write(callback + "({'name':'huangbiao','age':'11'});"); pw.flush(); pw.close(); } }