Ajax跨域和综合案例
一、ajax跨域
1.什么是跨域?
域名组成:
http:// www . hello.com : 8080 / myproject/abc.html
协议 子域名 主域名 端口号 资源地址
怎么才算跨域?
当协议、子域名、主域名、端口号中任意一个不同,都算作跨域。
跨域会怎样?
我们的项目部署的时候拆分成多个模块部署在不同的服务器中.
项目1部署在一个tomcat 8080
项目2部署在一个tomcat 端口是8081
如果使用项目2中的页面方式项目1的资源,能否访问到? 不能!! 因为跨域了.(会受到同源策略保护)
演示跨域:
准备两个项目,部署在不同的tomcat中,tomcat我们需要修改端口
day18部署在tomcat8.5 端口 8080服务器上
day18_2 部署在tomcat8 端口8081 的服务器上
项目day18_2中编写ajax请求,请求的路径写成day18项目的资源. (查看是否跨域)
跨域问题的图解:
问题显示:
如果跨域访问不到如何解决.
2.如何解决跨域问题
为什么要解决跨域?
方式1代理方案
把ajax请求其他服务器上的跨域问题进行转换,变成先请求自己的后台服务,通过后台服务间的调用,避免了ajax访问别的服务产生的跨域问题.
方式2: jsonp:
为什么是jsonp:
JSONP(JSON with Padding)是JSON的一种“使用模式”,可用于解决主流浏览器的跨域数据访问的问题.
由于同源策略,一般来说位于 server1.example.com 的网页无法与不是 server1.example.com的服务器沟通,而 HTML 的<script> 元素是一个例外。
利用 <script> 元素的这个开放策略,网页可以得到从其他来源动态产生的 JSON 资料,而这种使用模式就是所谓的 JSONP。
用 JSONP 抓到的资料并不是 JSON,而是任意的JavaScript,用 JavaScript 直译器执行而不是用 JSON 解析器解析。
总结:jsonp 可以解决浏览器跨域问题; 使用<script>标签来解决 ,因为<script>标签开放了同源保护策略.
演示<script>能够跨域:
因为jsonp底层解决跨域就是根据<script>标签来解决的.
方式3:XHR2全称XMLHttpRequest Level2
他属于html5的跨域解决方式. 如果是IE10以上 和一些主流的版本的浏览器有该跨域功能.
主要处理的问题在移动端.
3.jsonp的2中使用方式
$.ajax()
1.修改我们ajax中的dataType类型为"jsonp"
2.在被访端的后台
获取"callback"参数
给写回的数据添加新的格式: reponse.getWriter().print(callback+"("+json+")");
最后回调函数中的参数是一个json对象.
代码演示:
day18_2 里面的
/*
* 编写一个ajax请求day18下的一个Servlet资源
* */
$.ajax({
url:"http://127.0.0.1:8081/day18/ServletDemo",
//url:"http://localhost:8080/day18_2/ServletDemo1",
async:true,
data:"name=tom",
type:"GET",
dataType:"jsonp",
success:function(data){ //{"username":"tom","age":18}
alert(data.username + " "+ data.age);
}
})
day18项目中
@WebServlet("/ServletDemo")
public class ServletDemo extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.需要获取一个参数callback
String callback = request.getParameter("callback");
User user = new User("tom",18);
ObjectMapper om = new ObjectMapper();
String json = om.writeValueAsString(user); //{"username":"tom","age":18}
//response.getWriter().print(json);
//2.转换传出的数据类型
response.getWriter().print(callback+"("+json+")");
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
$.getJson() 其实原理与$.ajax一致,他是一个简化版本
//我们没有设置dataType ,默认是jsonp 默认请求类型GET 默认异步
$.getJSON("http://127.0.0.1:8081/day18/ServletDemo?callback=?","name=jack",function(data){
alert(data.username + " "+ data.age);
})
后台和原来一样,也需要修改.(修改方式一样)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="js/jquery-3.3.1.js"></script>
<script>
$(function(){
$("#btn").click(function(){
var name = $("#uid").val();
//第三种方式
$.ajax({
url:"http://localhost:8082/day18_2/Demo2Servlet",
data: {"name":name},
dataType:"jsonp",
type:"post",
success:function(data){
alert(data.name + data.age);
},
error:function(){
alert("响应失败");
}
})
})
})
</script>
</head>
<body>
<input type="text" name="username" id="uid"/><br/>
<input type="button" value="ajax发送请求" id="btn"/>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="js/jquery-3.3.1.js"></script>
<script>
$(function(){
$("#btn").click(function(){
//getJson 发送ajax请求默认的请求方式是jsonp
$.getJSON("http://localhost:8082/day18_2/Demo3Servlet?callback=?","name=tom",function(data){
alert(data.name + " , "+data.age);
})
})
})
</script>
</head>
<body>
<input type="text" name="username" id="uid"/><br/>
<input type="button" value="ajax发送请求" id="btn"/>
</body>
</html>
package com.itheima.web;
import com.fasterxml.jackson.databind.ObjectMapper;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/Demo2Servlet")
public class Demo2Servlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.设置编码
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=utf-8");
//2.接受参数
String callback = request.getParameter("callback");
Person p = new Person("张三",19);
ObjectMapper om = new ObjectMapper();
String personJson = om.writeValueAsString(p);
//3.响应数据
response.getWriter().print(callback+"("+personJson+")");
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
package com.itheima.web;
import com.fasterxml.jackson.databind.ObjectMapper;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/Demo3Servlet")
public class Demo3Servlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.设置编码
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=utf-8");
//2.接受参数
String callback = request.getParameter("callback");
String name = request.getParameter("name");
System.out.println(name);
Person p = new Person("李四",20);
ObjectMapper om = new ObjectMapper();
String personJson = om.writeValueAsString(p);
//3.响应数据
response.getWriter().print(callback+"("+personJson+")");
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
package com.itheima.web;
public class Person {
private String name;
private int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}