049:基于Nginx实现解决网站跨域问题
1 在Linux服务器上安装Nginx服务器
课程内容:
1、在Linux环境上安装Nginx需要注意的事项
2、实际项目中网站跨域产生的背景
3、史上最全的网站跨域问题解决方案
4、基于Nginx实现解决网站跨域问题
5、root、alias指令区别
Linux环境Nginx安装
1.安装gcc gcc-c++(如新环境,未安装请先安装)
$ yum install -y gcc gcc-c++
2.安装wget
$ yum -y install wget
3.安装PCRE库
$ cd /usr/local/
$ wget http://jaist.dl.sourceforge.net/project/pcre/pcre/8.33/pcre-8.33.tar.gz
$ tar -zxvf pcre-8.33.tar.gz
$ cd pcre-8.33
$ ./configure
$ make && make install
4.安装SSL库
$ yum install openssl
$ yum update openssl
5.安装zlib库
$ cd /usr/local/
$ wget http://zlib.net/zlib-1.2.11.tar.gz
$ tar -zxvf zlib-1.2.11.tar.gz
$ cd zlib-1.2.11
$ ./configure
$ make && make install
6.安装nginx
$ cd /usr/local/
$ wget http://nginx.org/download/nginx-1.8.0.tar.gz
$ tar -zxvf nginx-1.8.0.tar.gz
$ cd nginx-1.8.0
$ ./configure
$ make && make install
7.启动nginx
/usr/local/nginx/sbin/nginx
测试启动nginx成功
2 Nginx root、alias指令区别
root 、alias指令区别
alias是一个目录别名的定义,root则是最上层目录的定义。
有一个重要的区别是alias后面必须要用“/”结束,否则会找不到文件,而root则可有可无。
查找nginx应用
ps -aux | grep ‘nginx’
关闭防火墙
systemctl stop firewalld
停止nginx
/usr/local/nginx/sbin/nginx -s stop
测试alias效果:
3 Nginx快速回顾实现反向代理技术
4 实际项目中跨域问题产生的背景
什么是跨域的问题
当浏览器请求中访问页面时,如果当前页面中的ajax域名和端口号与当前页面访问的请求域名和端口号都不一致的情况下,浏览器有自我保护机制,能够访问到该请求但是无法获取结果集。
跨域问题的遇到场景
实际开发中前后端分离
模拟网站跨域问题
A项目
@Controller
@SpringBootApplication
public class AIndexController {
@ResponseBody
@RequestMapping("/")
public String index() {
return "蚂蚁课堂A项目";
}
@RequestMapping("/aIndexJsp")
public String aIndexJsp() {
return "aIndexJsp";
}
public static void main(String[] args) {
SpringApplication.run(AIndexController.class, args);
}
}
server:
port: 8080
spring:
mvc:
view:
prefix: /WEB-INF/jsp/
suffix: .jsp
<%@ 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="http://code.jquery.com/jquery-latest.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$.ajax({
type : "POST",
async : false,
url : "http://127.0.0.1:8081/getBInfo",
dataType : "json",
success : function(data) {
alert(data["retCode"]);
},
error : function() {
alert('fail');
}
});
});
</script>
</head>
<body>A项目正在调用B项目
</body>
</html>
B项目
@RestController
@SpringBootApplication
public class BIndexController {
@RequestMapping("/")
public String index() {
return "我是B项目";
}
//该接口提供给A项目进行ajax调用
@RequestMapping("/getBInfo")
public Map<String, Object> getBInfo(HttpServletResponse response) {
System.out.println(">>>>>>B项目getBInfo>>>>>>");
Map<String, Object> result = new HashMap<String, Object>();
result.put("retCode", "200");
result.put("retMsg", "登陆成功");
return result;
}
public static void main(String[] args) {
SpringApplication.run(BIndexController.class, args);
}
}
server:
port: 8081
运行结果:
5 基于JSONP解决项目中跨域问题
网站跨域的问题如何实现解决
1.服务端设置响应允许跨域;
2.使用jsonp实现解决 缺点:只能够发送get请求;模拟script提交参数;
3.基于Nginx实现统一接口的域名和端口号;
4.使用微服务中的网关解决跨域问题;
5.使用HttpClient实现转发,和nginx反向代理原理一样;
1.服务端设置响应允许跨域
@RequestMapping("/getBInfo")
public Map<String, Object> getBInfo(HttpServletResponse response) {
System.out.println(">>>>>>B项目getBInfo>>>>>>");
// 告诉客户端(浏览器)允许跨域访问 *表示所有域名都是可以 在公司中正常的代码应该放入在过滤器中
// 小项目合适 Aop/过滤器 响应头设置允许跨域解决代码重复问题
response.setHeader("Access-Control-Allow-Origin", "*");
Map<String, Object> result = new HashMap<String, Object>();
result.put("retCode", "200");
result.put("retMsg", "登陆成功");
return result;
}
2.使用jsonp实现解决
A项目Ajax相关配置
<script type="text/javascript">
$(document).ready(function () {
$.ajax({
type: "post",
async: false,
url: "http://api.mayikt.com/b/getBInfo?callback=",
dataType: "jsonp",
jsonp: "jsonpCallback",
jsonpCallback: "callback",
success: function (data) {
alert(data["retMsg"]);
},
error: function (msg) {
alert(msg.toString());
}
});
});
</script>
B项目服务端
// 使用jsonp 解决跨域问题
@RequestMapping("/getBInfo")
public void getBInfo(HttpServletResponse response, String jsonpCallback)
throws IOException {
JSONObject result = new JSONObject();
result.put("retCode", "200");
result.put("retMsg", "登陆成功");
PrintWriter writer = response.getWriter();
writer.println(jsonpCallback + "(" + result.toJSONString() + ")");
writer.close();
// 127.0.0.1:8081?jsonpCallback=256163154
// B项目返回结果集 256163154(jsonObject)
}
测试结果:
6 使用HttpClient实现转发请求解决跨域
3.使用HttpClient实现转发
<script type="text/javascript">
$(document).ready(function () {
$.ajax({
type: "POST",
async: false,
url: "http://127.0.0.1:8080/forWardB",
dataType: "json",
success: function (data) {
alert(data["retCode"]);
},
error: function () {
alert('fail');
}
});
});
</script>
// 使用HttpClient进行方法B接口
@RequestMapping("/forWardB")
@ResponseBody
public JSONObject forWardB() {
// 中间采用rpc httpClient技术调用接口。服务器与服务器之间不存在跨域问题
JSONObject result = HttpClientUtils.httpGet("http://127.0.0.1:8081/getBInfo");
return result;
}
测试结果:
7 基于Nginx构建微服务网关解决跨域
大型互联网公司解决跨域问题,使用Nginx实现网关或者使用微服务网关
4.使用Nginx搭建网关
保持域名相同,根据项目名称不同实现转发
本地hosts文件增加 192.168.0.50 api.mayikt.com
192.168.0.50为虚拟机ip,192.168.43.179为本机ip
Nginx搭建网关测试结果