跨域请求的解决方案

1 本节任务

理解 ajax 的跨域访问

2Ajax 跨域介绍

跨域,指的是浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器

对 JavaScript 施加的安全限制。

什么是同源策略: 所谓的同源,指的是域名、协议、端口均相等。

不同源的系统使用 ajax 发送求,会存在跨域的问题:例如

http://www.abc.com/ 访问 http://www.xyz.com 域名不一致,存在跨域

http://www.abc.com/ 访问 https://www.abc.com 协议不一致,存在跨域

http://www.abc.com:80/ 访问 http://www.abc.com:81 端口不一致,存在跨域

3Ajax 跨域问题

3.1 建立 ajax-origin 项目

<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.bjsxt.ajax.origin</groupId> <artifactId>ajax-origin</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>war</packaging> <properties>
<!-- spring 依赖 --> <spring.version>4.3.18.RELEASE</spring.version> <jstl.version>1.2</jstl.version> <servlet-api.version>2.5</servlet-api.version> <jsp-api.version>2.0</jsp-api.version> <jackson.version>2.9.0</jackson.version>
</properties> <dependencies>
<!-- jsp 相关依赖 -->
<!-- servlet 依赖 -->
<!-- jstl 依赖 --> <dependency> <groupId>jstl</groupId> <artifactId>jstl</artifactId> <version>${jstl.version}</version>
</dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>${servlet-api.version}</version> <scope>provided</scope>
</dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>jsp-api</artifactId> <version>${jsp-api.version}</version> <scope>provided</scope>
</dependency>
</dependencies> <build> <finalName>ajax</finalName> <plugins>
<!-- 配置 Tomcat 插件 --> <plugin> <groupId>org.apache.tomcat.maven</groupId> <artifactId>tomcat7-maven-plugin</artifactId> <version>2.2</version> <configuration> <path>/ajax</path> <port>9090</port>
</configuration>
</plugin>
</plugins>
</build>
</project>

3.2 发送 Ajax 请求

<%@ 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>
<script type="text/javascript" src="https://code.jquery.com/jquery-1.11.3.js"></script>
<script type="text/javascript">
function sendAjax(){
$.post("http://localhost:7070/order/loadOrderList02","uid=1234",function(data){
alert(data);
});
}
</script>
</head> <body><a href="javascript:sendAjax()">sendAjax</a>
</body>
</html>

3.3 观察跨域问题

4Ajax 跨域解决方案

4.1 服务器段解决

服务端设置 response header 中 Access-Control-Allow-Origin 字段

4.2 前端 JSONP 解决

利用 script 标签,不受同源策略的限制,用户从服务请求数据,服务器返回一个带有方法和数据

的 js 代码。

1 本节任务

服务器段,使用 CORSFilter 过滤器解决跨域问题

2CORSFilter 解决跨域访问原理

通过 CORSFilter 过滤器在服务器端修改 Http 的响应头

Access-Control-Allow-Origin: *

Access-Control-Allow-Origin: http://example.com:8080/

3 修改 order-sys 项目

3.1 添加 CORSFilter 依赖

<dependency> <groupId>com.thetransactioncompany</groupId> <artifactId>cors-filter</artifactId> <version>2.5</version> <scope>runtime</scope>
</dependency>

3.2web.xml 配置 CORSFilter

<filter> <filter-name>CORS</filter-name> <filter-class>com.thetransactioncompany.cors.CORSFilter</filter-class> <init-param>
<param-name>cors.allowOrigin</param-name>
<param-value>*</param-value>
</init-param> <init-param> <param-name>cors.supportedMethods</param-name> <param-value>GET, POST, HEAD, PUT, DELETE</param-value>
</init-param> <init-param> <param-name>cors.supportedHeaders</param-name> <param-value>Accept, Origin, X-Requested-With, Content-Type,
Last-Modified</param-value>
</init-param> <init-param> <param-name>cors.exposedHeaders</param-name> <param-value>Set-Cookie</param-value>
</init-param> <init-param> <param-name>cors.supportsCredentials</param-name> <param-value>true</param-value>
</init-param>
</filter> <filter-mapping> <filter-name>CORS</filter-name> <url-pattern>/*</url-pattern>
</filter-mapping>

3.3 启动 order-sys 项目

4 启动 ajax-origin 测试

<!-- fastjson --> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.47</version>
</dependency>

3.3 修改 OrderController 类

Controller 添加一个接收远程 ajax 请求的方法,该方法后一个接收回调函数的参数.

/****
* 接收 jsonp 请求,响应 js 的字符串到客户端
* @param uid
* @param callback
* @return
*/
@RequestMapping("/loadOrderList03")
@ResponseBody
public String loadOrderList03(String uid,String callback){
System.out.println("uid="+uid);
Order o1=new Order();
o1.setId("111");
o1.setTotal(123.0);
o1.setDate("2018-10-10");
Order o2=new Order();
o2.setId("222");
o2.setTotal(1232.0);
o2.setDate("2018-10-13");
Order o3=new Order();
o3.setId("333");
o3.setTotal(333.0);
o3.setDate("2018-10-31");
List<Order> list = new ArrayList<>();
list.add(o1);
list.add(o2);
list.add(o3);
//result 是需要响应到客户端的 js 代码
String result=callback+"("+JSON.toJSONString(list)+")";
return result; }

3.4 启动 order-sys 项目

4 修改 ajax-origin 项目

4.1 导入 juqery 函数库

<script type="text/javascript" src="https://code.jquery.com/jquery-1.11.3.js"></script>

4.2 发送请求

利用<script src="url?callback=doSomething"></script>发送请求

<script
src="http://localhost:7070/order/loadOrderList03?uid=9999&callback=doCallback"></script>

4.3 定义 callback 回调函数

function doCallback(data){
//将 json 对象转化为字符串
var str=JSON.stringify(data);
alert(str);
}

4.4 启动 ajax-origin 测试

5jquery 对 jsonp 支持

function sendAjax(){
/* $.post("http://localhost:7070/order/loadOrderList02","uid=1234",function(data){
alert(data);
});
*/
$.getJSON("http://localhost:7070/order/loadOrderList03?callback=?","uid=1234",
function(data){
//将 json 对象转化为字符串
var str=JSON.stringify(data);
alert(str);
});
}

3RMI 模拟服务器集群部署

3.1 建立 rmi-cluster-provider 项目

3.2 建立 UserService 接口

package com.bjsxt.service;
import java.rmi.Remote;
import java.rmi.RemoteException;
/***
* 创建需要发布的服务对应的业务接口
* @author Administrator
* Remote 接口用于标识其方法可以从非本地虚拟机上调用的接口。
*/
public interface UserService extends Remote{
public String helloRmi(String name) throws RemoteException;
}

3.3 建立 UserServiceImpl 实现类

package com.bjsxt.service.impl;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import com.bjsxt.service.UserService;
/***
* 创建发布的服务对应的实现类
* @author Administrator
*
*/
public class UserServiceImpl
extends UnicastRemoteObject implements UserService {
public UserServiceImpl() throws RemoteException {
super();
// TODO Auto-generated constructor stub
}
@Override
public String helloRmi(String name) throws RemoteException {
// TODO Auto-generated method stub
return "hello "+name; } }

3.4 发布集群服务

启动程序三次,每次启动修改端口号,实现服务的集群部署

package com.bjsxt.app;
import java.rmi.Naming;
import java.rmi.registry.LocateRegistry;
import com.bjsxt.service.UserService;
import com.bjsxt.service.impl.UserServiceImpl;
public class ProviderApp {
public static void main(String[] args) {
try{
/****
* 完成远程服务的发布
*/
//将远程服务发布在本地的 8888 端口
LocateRegistry.createRegistry(8888);
//发布的远程服务的访问 url
String name="rmi://localhost:8888/rmi";
//创建一个提供具体服务的远程对象
UserService userService = new UserServiceImpl();
//给提供远程服务的对象绑定一个 url
Naming.bind(name, userService);
System.out.println("=============发布 rmi 远程服务============");
}catch(Exception ex){
ex.printStackTrace();
} } }

4RMI 消费集群服务

4.1 建立 rmi-cluster-consumer 项目

4.2 拷贝 UserService 接口

4.3 实现集群服务消费

package com.bjsxt.app;
import java.rmi.Naming;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;
import com.bjsxt.service.UserService;
public class ConsumerApp {
public static void main(String[] args) {
List<String> urls = new ArrayList<String>();
urls.add("rmi://localhost:7777/rmi");
urls.add("rmi://localhost:8888/rmi");
urls.add("rmi://localhost:9999/rmi");
String url =null;
while(true){
try{
//通过随机的负载均衡算法,产生随机的访问地址
int index=ThreadLocalRandom.current().nextInt(urls.size());
//发布的远程服务的访问 url
url = urls.get(index);
//通过发布的远程服务的 url,获得远程服务的代理对象
UserService userService = (UserService) Naming.lookup(url);
System.out.println("获得的远程服务的代理对象:"
+userService.getClass().getName());
//通过远程服务的代理对象调用远程服务方法
String result = userService.helloRmi("===="+url+"======= rmi");
System.out.println("result="+result);
Thread.sleep(3000);
}catch (Exception e) {
// TODO: handle exception
urls.remove(url); //剔除不可用的服务的地址
e.printStackTrace();
} } } }

原文地址:https://www.cnblogs.com/wq-9/p/11751232.html

时间: 2024-10-21 22:25:14

跨域请求的解决方案的相关文章

跨域请求数据解决方案整理

转自:http://www.cnblogs.com/xyang/archive/2012/05/18/2507845.html 跨域请求数据解决方案主要有如下解决方法: JSONP方式 表单POST方式 服务器代理 Html5的XDomainRequest Flash request 分开说明: 一.JSONP: 直观的理解: 就是在客户端动态注册一个函数 function a(data),然后将函数名传到服务器,服务器返回一个a({/*json*/})到客户端运行,这样就调用客户端的 func

JQuery的Ajax跨域请求的解决方案

http://www.open-open.com/lib/view/open1334026513327.html 今天在项目中需要做远程数据加载并渲染页面,直到开发阶段才意识到ajax跨域请求的问题,隐约记得Jquery有提过一个ajax跨域请求的解决方式, 于是即刻翻出Jquery的API出来研究,发现JQuery对于Ajax的跨域请求有两类解决方案,不过都是只支持get方式.分别是JQuery的 jquery.ajax jsonp格式和jquery.getScript方式. 什么是jsonp

ajax跨域请求解决方案

大家好,今天我们学习了js的跨域请求的解决方案,由于JS中存在同源策略,当请求不同协议名,不同端口号.不同主机名下面的文件时,将会违背同源策略,无法请求成功!需要进行跨域处理! 方案一.后台PHP进行设置, 前台无需任何设置,在后台被请求的PHP文件中,写入一条header header("Access-Control-Allow-Origin:*"); 表示允许那些域名请求这个PHP文件*表示所有域名都允许 这是最佳的解决方案,因为是在后台进行设置,不对外公开,所以更加安全, 方案二

js跨域请求方式 ---- JSONP原理解析

这篇文章主要介绍了js跨域请求的5中解决方式的相关资料,需要的朋友可以参考下 跨域请求数据解决方案主要有如下解决方法: 1 2 3 4 5 JSONP方式 表单POST方式 服务器代理 Html5的XDomainRequest Flash request 分开说明: 一.JSONP: 直观的理解: 就是在客户端动态注册一个函数 function a(data),然后将函数名传到服务器,服务器返回一个a({/*json*/})到客户端运行,这样就调用客户端的 function a(data),从而

Ajax+Spring MVC实现跨域请求(JSONP)JSONP 跨域

JSONP原理及实现 接下来,来实际模拟一个跨域请求的解决方案.后端为Spring MVC架构的,前端则通过Ajax进行跨域访问. 1.首先客户端需要注册一个callback(服务端通过该callback(jsonp)可以得到js函数名(jsonpCallback)),然后以JavaScript语 法的方式,生成一个function 2.接下来,将JSON数据直接以入参的方式,放置到function中,这样就生成了一段js语法文档,返回给客户端. 3.最后客户端浏览器动态的解析script标签,

Ajax+Spring MVC实现跨域请求(JSONP)

JSONP解释 在解释JSONP之前,我们需要了解下"同源策略"这个概念,这对理解跨域有帮助.基于安全的原因,浏览器是存在同源策略机制的,同源策略阻止从一个源加载的文档或脚本获取或设置另一个源加载额文档的属性.有点绕,说的简单点就是浏览器限制脚本只能和同协议.同域名.同端口的脚本进行交互. JSONP就是为了解决这一问题的,JSONP是英文JSON with Padding的缩写,是一个非官方的协议.他允许服务端生成script tags返回值客户端,通过javascript call

Ajax+Spring MVC实现跨域请求(JSONP)(转)

背景: AJAX向后台(springmvc)发送请求,报错:已阻止交叉源请求:同源策略不允许读取 http://127.0.0.1:8080/DevInfoWeb/getJsonp 上的远程资源.可 以将资源移动到相同的域名上或者启用 CORS 来解决这个问题. 百度一下,发现是遇到了跨域请求请求问题.搜集资料如下 JSONP解释 在解释JSONP之前,我们需要了解下"同源策略"这个概念,这对理解跨域有帮助.基于安全的原因,浏览器是存在同源策略机制的,同源策略阻止从一个源加载的文档或脚

4.同源策略与跨域请求

一.同源策略基本概念 1.同源策略概念: 一种约定,它是浏览器最核心也是最基本的安全功能,同源指域名.协议.端口需要保持一直才能进行相互间的访问. 2.例子: (1)http://a.com没有办法访问到http://b.com下的脚本文件和文档. (2)浏览器采用同源策略,禁止页面加载或执行与自身那个来源不同的域的任何脚本.换句话说浏览器禁止的是来源不同的“document”或脚本用来对当前“document”读取或设置某些属性. (3)哪些不受同源限制 <script>.<img&g

跨域请求解决方案

在前端开发过程中,难免和服务端产生数据交互.一般情况我们的请求分为这么几种情况: 只关注发送,不关注接收 不仅要发送,还要关注服务端返回的信息 同域请求 跨域请求 上面提到了一个概念,我们这里简单做一下讲解.什么叫做跨域?一般情况下,跨域分为三种情况:跨协议.跨子域.跨域名.下面距离梳理一下这三种情况. 跨协议:比如说我现在的域名地址是http://www.12306.cn,有一些请求需要发送到https://www.12306.cn,此时这个请求相对与http://www.12306.cn来说