
正文
基于前后端分离的Nginx+Tomcat动静分离
提示:扫一扫查出行【扫一扫了解最新限行尾号】
复制提示
1.什么是动静分离
“动”与“静”
在弄清动静分离之前,我们要先明白什么是动,什么是静。
在Web开发中,通常来说,动态资源其实就是指那些后台资源,而静态资源就是指Html、img、js、css等文件。
动静分离就是将动态资源和静态资源分开,将静态资源部署在Nginx上,当一个请求来的时候,如果是静态资源的请求,就直接到nginx配置的静态资源目录下面获取资源,如果是动态资源的请求,nginx利用反向代理的原理,把请求转发给后台应用去处理,从而实现动静分离。
好处
tomcat的优势在于少量的接收并处理复杂的http请求(将用户请求读写数据库等),nginx的优势在于能够大量的接收并处理简单的http请求(将http请求转发或者加个header、body等)。
将Html、img、js、css等这种静态资源交给nginx,将用户需要读写数据库等请求交给tomcat是对各自优势的最大利用。
详解
Nginx与tomcat各自的优势与区别详解参考:tomcat 与 nginx,apache的区别是什么?.
2.环境准备
需要nginx、tomcat、SpringBoot
2.1 linux
linux环境下的nginx下载、安装、使用
linux环境下的jdk8下载、安装、使用
linux环境下的tomcat下载、安装、使用
2.2 windows
windows环境下nginx下载解压后,即可使用。
Windows下Nginx的启动、停止等命令
由于使用SpringBoot,所以使用内嵌的tomcat。
3.正式部署3.1 前台
前台使用一个ajax请求后端,新建一个index.html
<!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>前后端分离</title> <script type="text/javascript" src="https://cdn.bootcss.com/jquery/1.11.2/jquery.js"></script> <script type="text/javascript"> $(function(){ $("#loginBtn").click(function(){ $.post( "http://localhost:8080/username", function(rtn){ $("#name").text(rtn.username) }); }); }); </script> </head> <body> <form> <input type="button" value="查看当前用户" id="loginBtn"> <div id="name" style="color:#00FF00"> </div> </form> </body></html>
将index.html放到nginx的html目录下(将nginx/html目录下的文件都删了)。
正式部署时,只需要将静态资源扔到html目录下即可
3.2 后台
后台使用SpringBoot,只需一个接收请求的controller即可,这里为了省事,直接在Application里面写controller了。
package com.example.demo;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import org.springframework.web.bind.annotation.RestController;@SpringBootApplication@RestControllerpublic class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } @RequestMapping(value = "/username", method = {RequestMethod.GET, RequestMethod.POST}) public User username() { // 假装请求了数据库 User user = new User("tom"); return user; } class User { private String username; public User(String username) { this.username = username; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } }}
启动SpringBoot项目可以访问到

正式部署时,只需要将SpringBoot打的jar包扔到服务器上启动即可
//打jarmvn clean package -Dmaven.test.skip=true//启动jarnohup java -jar ROOT.jar &
3.3 nginx.conf
worker_processes 1;events { worker_connections 1024;}http { include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; server { #监听8080端口,代理前端请求 listen 80; server_name localhost; location / { # 默认访问html下的index.html index index.html; } } server { #监听8080端口,代理后端请求 listen 8080; server_name localhost; location / { proxy_pass http://localhost:8080; proxy_set_header X-Real-IP $remote_addr; } }}
启动nginx
start nginx
nginx.conf的更多配置
Nginx反向代理、负载均衡、动静分离、缓存、压缩、防盗链、跨域访问
nginx.conf详细配置
3.4前后端分离导致动静分离的跨域问题
访问http://localhost/

Access to XMLHttpRequest at 'http://localhost:8080/username' from origin 'http://localhost' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
由于前后端分离了,所以前端http://localhost/使用ajax请求http://localhost:8080/发生了跨域问题。
详解:
CORS解决跨域问题
Jsonp解决跨域问题
这里直接给出解决方案,使用CORS解决跨域问题
import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.web.cors.CorsConfiguration;import org.springframework.web.cors.UrlBasedCorsConfigurationSource;import org.springframework.web.filter.CorsFilter;@Configurationpublic class GlobalCorsConfig { @Bean public CorsFilter corsFilter() { //1.添加CORS配置信息 CorsConfiguration config = new CorsConfiguration(); //1) 允许的域,不要写*,否则cookie就无法使用了 config.addAllowedOrigin("http://localhost"); //2) 是否发送Cookie信息 config.setAllowCredentials(true); //3) 允许的请求方式 config.addAllowedMethod("GET"); config.addAllowedMethod("POST"); config.addAllowedMethod("OPTIONS"); config.addAllowedMethod("HEAD"); config.addAllowedMethod("PUT"); config.addAllowedMethod("DELETE"); config.addAllowedMethod("PATCH"); // 4)允许的头信息 config.addAllowedHeader("*"); //2.添加映射路径,我们拦截一切请求 UrlBasedCorsConfigurationSource configSource = new UrlBasedCorsConfigurationSource(); configSource.registerCorsConfiguration("/**", config); //3.返回新的CorsFilter. return new CorsFilter(configSource); }}
放到Application.java同目录及以下即可
结构:

重启项目,再次访问http://localhost/,访问成功。

4.总结
总的来说就是将静态资源html、js、css等放入nginx中,将动态请求交给tomcat。
如果发生跨域,需要在解决跨域问题。
5.答疑
Q:该例子就一个html静态资源为什么不放到项目的static下?放到static下不就不会跨域了吗?
A:因为这只是一个例子,模拟动静分离。一个真实的项目,可能将html等静态资源放到不同于后台的服务、或者CDN上,那时候就一定会发生跨域问题。








