1. 跨域介绍
不同的域名或不同的端口都是跨域问题
www.a.comàwww.b.com 是跨域
www.a.comàwww.a.com:8080 是跨域
www.a.comàwww.a.com/api 不是跨域
2. 跨域问题用jsonp解决
1. jsonp原理
1.创建Maven中的war工程testA
2.在src/main/webapp里放入jquery,js.jsp(用来模拟从控制层返回数据),testA.html(用ajax来接收从控制层返回的参数)
js.jsp <%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <% out.print("{"name":123}"); %> testA.html <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>testA</title> </head> <body> </body> <script type="text/javascript" src="http://127.0.0.1:7001/jquery-3.2.1.min.js"></script> <script type="text/javascript"> alert($); $.ajax({ url:"http://127.0.0.1:7001/js.jsp", async:"false", success:function(d){ alert(d); } }); </script> </html> |
3.pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.test</groupId> <artifactId>testA</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>war</packaging> <dependencies> <!-- 为了去除jsp页面头部的错误 --> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> <scope>provided</scope> </dependency> </dependencies> <build> <plugins> <plugin> <!-- 配置端口为7001的tomcat,web应用服务器 --> <groupId>org.apache.tomcat.maven</groupId> <artifactId>tomcat7-maven-plugin</artifactId> <configuration> <port>7001</port> <path>/</path> </configuration> </plugin> </plugins> </build> </project> |
4.testA工程结构
5.结果如下,说明可以访问到本地的jquery和从本地的控制层返回的数据。
6.创建Maven的war工程testB
7.在src/main/webapp里创建测试用来跨域接收数据的testB.html
testB.html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>testB</title> </head> <body> </body> <script type="text/javascript" src="http://127.0.0.1:7001/jquery-3.2.1.min.js"></script> <script type="text/javascript"> alert($); $.ajax({ url:"http://127.0.0.1:7001/js.jsp", async:"false", success:function(d){ alert(d); } }); </script> </html> |
8.testB的pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.test</groupId> <artifactId>testA</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>war</packaging> <dependencies> <!-- 为了去除jsp页面头部的错误 --> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> <scope>provided</scope> </dependency> </dependencies> <build> <plugins> <plugin> <!-- 配置端口为7001的tomcat,web应用服务器 --> <groupId>org.apache.tomcat.maven</groupId> <artifactId>tomcat7-maven-plugin</artifactId> <configuration> <port>7002</port> <path>/</path> </configuration> </plugin> </plugins> </build> </project> |
9.testB工程结构:
10.运行结果
11.看出来alert($);正常跨域成功!而从控制层输出的数据跨域失败,报错(No 'Access-Control-Allow-Origin':没有“允许源访问控制”)。
12.可以用<script type="text/javascript" src="http://127.0.0.1:7001/jquery-3.2.1.min.js"></script>来实现跨域。修改testB中testB.html代码。
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>testB</title> </head> <body> </body> <script type="text/javascript" src="http://127.0.0.1:7001/jquery-3.2.1.min.js"></script> <script type="text/javascript"> /* $.ajax({ url:"http://127.0.0.1:7001/js.jsp", async:"false", success:function(d){ alert(d); } }); */ </script> <script type="text/javascript" src="http://127.0.0.1:7001/js.jsp"></script> </html> |
13.运行结果是没法解析的js
14.把testA中的js.jsp修改为
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <% out.print("alert({"name":123})"); %> |
15.运行结果:能打印出跨域接收的数据
16.再把testA中的js.jsp修改为
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <% out.print("fun({"name":123})"); %> |
17.运行结果:fun没定义
18.再修改testB中的testB.html
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>testB</title> </head> <body> </body> <script type="text/javascript" src="http://127.0.0.1:7001/jquery-3.2.1.min.js"></script> <script type="text/javascript"> /* $.ajax({ url:"http://127.0.0.1:7001/js.jsp", async:"false", success:function(d){ alert(d); } }); */ function fun(d){ alert(d); } </script> <script type="text/javascript" src="http://127.0.0.1:7001/js.jsp"></script> </html> |
19.运行结果:打印出结果
20.在控制层返回json字符串数据时,在json字符串前添加一个方法名再用小括号括起json字符串,再在网页定义刚刚方法名的方法,再用<script src=””></script>引用就可以实现跨域。这也是jsonp的实现原理。
2. jquery使用ajax跨域
1.jsonp在jquery的ajax里添加一行dataType:”jsonp”,也能实现跨域,不过控制层也需要修改。
js.jsp <%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <%
out.print(request.getParameter("callback")+"({"name":123})"); %> testB.html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>testB</title> </head> <body> </body> <script type="text/javascript" src="http://127.0.0.1:7001/jquery-3.2.1.min.js"></script> <script type="text/javascript"> $.ajax({ url:"http://127.0.0.1:7001/js.jsp", async:"false", dataType:"jsonp", success:function(d){ alert(d); } }); </script> </html> |
2.运行结果:jquery的ajax跨域成功。