跨域
概念
同源策略是浏览器的一种安全策略,所谓同源是指域名、协议、端口号完全相同,只有同源的地址才可以相互通过AJAX的方式请求
同源或者不同源说的是两个地址之间的关系,不同源地址之间请求我们称之为跨域请求
同源策略限制以下几种行为:
(1)Cookie.LocalStorage和IndexDB无法读取
(2)DOM和js对象无法获得
(3)AJAX请求不能发送
什么是同源?
常见的跨域场景
跨域解决方案
1、通过jsonp跨域
2、document.domain+Iframe跨域
3、location.hash+Iframe
4、window.name+Ifname跨域
5、postMessage跨域
6、跨域资源共享(CORS)
7、nglnx代理跨域
8、nodejs中间件代理跨域
9、WebSocket协议跨域
JSONP
跨域的安全限制都是对浏览器端来说的,服务器端是不存在跨域安全限制的。
浏览器的同源策略限制从一个源加载的文档或脚本与来自另一个源的资源进行交互
如果协议、端口和主机对于两个页面是相同的,则两个页面具有相同的源,否则就是不同源的
如果要在js里发起跨域请求,则要进行一些特殊处理了,或者,你可以把请求发到自己的服务端,再通过后台代码发起请求,再将数据返回前端。
JSONP全称是JSON with Padding,是为了解决跨域请求资源而产生的解决方案,是一种依靠开发人员创造出的一种非官方跨域数据交互协议。一个是描述信息的格式,一个是信息传递双方约定的方法。
jsonp的产生:
1、AJAX直接请求普通文件存在跨域无权限访问的问题,不管是静态页面还是动态页面
2、不过我们在调用js文件的时候又不受跨域影响,比如引入jquery框架的,或者调用相片的时候
3、凡是拥有scr这个属性的标签都可以跨域,例如<script>、<img>、<iframe>
4、如果想通过纯web端跨域访问数据只有一种可能,那就是把远程服务器上的数据装进js格式的文件里
5、而json又是一个轻量级的数据格式,还被js原生支持
6、为了方便客户使用数据,逐渐形成了一种非正式传输协议,人们把它称作JSONP,该协议的一个要点就是允许用户传递一个callback参数给服务端。
使用:
创建如图所示两个文件
A----->index.jsp
<%--
Created by IntelliJ IDEA.
User: Administrator
Date: 2018/7/20
Time: 14:16
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
<script src="js/jquery-1.12.4.js"></script>
<script type="text/javascript">
$(function () {
$("#btn").click(function () {
$.get({
url:"http://localhost:8888/B/StdentServlet",
dataType:"jsonp",
jsonpCallback:"callback",
success: function (data) {
var result = JSON.stringify(data);
$("#datail").text(result);
}
})
})
})
</script>
</head>
<body>
<input type="button" id="btn" value="发送跨域请求">
<div id="datail">
</div>
</body>
</html>
B----->Student.java
package org.lanqiao.doem.controller;
import java.util.Objects;
public class Student {
private String stuName;
private String sex;
private int age;
public Student() {
}
public Student(String stuName, String sex, int age) {
this.stuName = stuName;
this.sex = sex;
this.age = age;
}
public String getStuName() {
return stuName;
}
public void setStuName(String stuName) {
this.stuName = stuName;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"stuName='" + stuName + '\'' +
", sex='" + sex + '\'' +
", age=" + age +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return age == student.age &&
Objects.equals(stuName, student.stuName) &&
Objects.equals(sex, student.sex);
}
@Override
public int hashCode() {
return Objects.hash(stuName, sex, age);
}
}
B------>StudentServlet.java
package org.lanqiao.doem.controller;
import com.alibaba.fastjson.JSON;
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;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
@WebServlet( "/StudentServlet")
public class StudentServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String callback = request.getParameter("callback");
response.setContentType("text/json");
response.setCharacterEncoding("UTF-8");
PrintWriter out = response.getWriter();
Student stu1 = new Student("张三","男",21);
Student stu2 = new Student("张四","女",25);
Student stu3 = new Student("张五","男",23);
List<Student> stuList = new ArrayList<>() ;
stuList.add(stu1);
stuList.add(stu2);
stuList.add(stu3);
String stuJson = JSON.toJSONString(stuList);
stuJson = callback +"("+stuJson+")";
out.write(stuJson);
out.close();
}
}
注意:这种是端口号不同,设置了两个不同的tomcat
CORS
CORS是一个W3C标准,全称是“跨域资源共享”(Cross-origin resource sharing)
它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制
整个CORS通信过程,都是浏览器自动完成,不需要用户参与,对于开发者来说,CORS通信与同源的AJAX通信没有差别,代码完全一样。浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉。
这种方案无需客户端作出任何变化(客户端不用改代码),只是在被请求的服务端响应的时候添加一个Access-Control-Allow-Origin的响应头,表示这个资源是否允许指定域请求。
response.setHeader("Access-Control-Allow-Origin","*");
package org.lanqiao.doem.controller;
import com.alibaba.fastjson.JSON;
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;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
@WebServlet( "/StudentServlet")
public class StudentServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String callback = request.getParameter("callback");
response.setContentType("text/json");
response.setCharacterEncoding("UTF-8");
response.setHeader("Access-Control-Allow-Origin","*");
PrintWriter out = response.getWriter();
Student stu1 = new Student("张三","男",21);
Student stu2 = new Student("张四","女",25);
Student stu3 = new Student("张五","男",23);
List<Student> stuList = new ArrayList<>() ;
stuList.add(stu1);
stuList.add(stu2);
stuList.add(stu3);
String stuJson = JSON.toJSONString(stuList);
stuJson = callback +"("+stuJson+")";
out.write(stuJson);
out.close();
}
}
上一篇: Linux shell脚本全面学习
下一篇: 常用的跨域解决方案