前后端分离总结

前言

对于刚入行时的小白误以为前后端分离就是,前端代码不使用java了。但是其实并不是这样的,前后端分离就是前段写前端的代码,后端完成后端的代码互不干扰。前端编写的时候,只要后端给提供相应的接口过去就可以了

1、跨域问题

URL 说明 是否允许通信
http://www.a.com/a.js 
http://www.a.com/b.js
同一域名下 允许
http://www.a.com/lab/a.js 
http://www.a.com/script/b.js
同一域名下不同文件夹 允许
http://www.a.com:8000/a.js 
http://www.a.com/b.js
同一域名,不同端口 不允许
http://www.a.com/a.js 
https://www.a.com/b.js
同一域名,不同协议 不允许
http://www.a.com/a.js 
http://70.32.92.74/b.js
域名和域名对应ip 不允许
http://www.a.com/a.js 
http://script.a.com/b.js
主域相同,子域不同 不允许
http://www.a.com/a.js 
http://a.com/b.js
同一域名,不同二级域名(同上) 不允许(cookie这种情况下也不允许访问)
http://www.cnblogs.com/a.js 
http://www.a.com/b.js
不同域名 不允许

1.1、前后端代码不在一个服务器上,域名也不一样,很明显就是要跨域

1.1.1、小白:什么是跨域

正常情况下,我们拿浏览器去访问的时候,直接访问后后端服务器,这样是不跨域,而跨域就是我们浏览器访问前端代码,通过前端代码访问后端服务器。这样就是跨域了。前端代码相当于是一个中介

1.1.2、配置拦截器

@Component
@Slf4j
public class CORSInterceptor extends HandlerInterceptorAdapter {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        //添加跨域CORS
//        服务器不在一起,下面这个跨域是马川 给我的,好用
        String originHeader = request.getHeader("Origin");
        response.setHeader("Access-Control-Allow-Origin", originHeader);
        response.addHeader("Access-Control-Allow-Headers", "Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With,accessToken");
        response.addHeader("Access-Control-Allow-Credentials", "true");
        response.setHeader("Access-Control-Allow-Methods", "GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS, PATCH");



        return true;
    }
}
@Configuration
public class InterceptorConfig extends WebMvcConfigurerAdapter{

    @Autowired //解决跨域
    private CORSInterceptor corsInterceptor;

       @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(corsInterceptor);

        super.addInterceptors(registry);

    }
}

1.1.3、将前端首页缓存下来(这样一来,每次我们登录之后不管方位的哪个页面都是首页)

(可以是redis,也可以是ehcache,也可以是数据库)

1、配置文件中首页的url,因为下面下面是使用的阿里云的服务器,所以用了下面的方法,大家也可以直接通过url进行缓冲首页面

2、这样的话就是相当于是走了前端代理了,使用的后端的url,打开之后访问的是前端。所以这里要求我们严格编写服务器url路径(设置一个url统一的前缀,比如我这里是duodian)

# 前后端分离
duodianyouhui.page.prefix=duodian-youhui-admin/index.html
package com.duodian.youhui.admin.moudle;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

import com.duodian.youhui.admin.Exceptions.AppException;
import com.duodian.youhui.admin.bean.ResponseBean;
import com.duodian.youhui.admin.config.CasConfig;
import com.duodian.youhui.admin.config.cache.EhCacheObjectDataUtil;
import com.duodian.youhui.admin.constants.CacheConstants;
import com.duodian.youhui.admin.utils.OSSPageUtil;
import com.duodian.youhui.admin.utils.SdkHttpHelper;
import com.duodian.youhui.data.http.HttpBackBean;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * @author chuan.ma
 * @since 2018/3/13
 */
@Controller
@Slf4j
public class IndexController {

    @Resource
    private EhCacheObjectDataUtil ehCacheObjectDataUtil;

    //前后端分离的首页
    @Value("${duodianyouhui.page.prefix}")
    private String asouPage;

    @RequestMapping("/**")
    public void index(HttpServletResponse response, HttpServletRequest request) throws Exception {
        String content = getPageCache();
        try {
            if (StringUtils.isEmpty(content)) {
//          将页面下载下来,也可以比使用oss下载,这里用的是oss,这里只传递了一个 首页面。所以以后都是登陆后进入首页面
                content = IOUtils.toString(OSSPageUtil.download(asouPage), "UTF-8");
//                HttpBackBean httpBackBean = SdkHttpHelper.handleGet("http://testquan.dangqugame.cn/duodian-youhui-admin/index.html", null, null, SdkHttpHelper.OVERTIME);
                setPageCache(content);
            }
        } catch (Exception e) {
            log.error(e.getMessage());
        }
        if(request.getRequestURI().contains("swagger")){

        }
            response.setContentType("text/html;charset=utf-8"); //相当于是将流变成的浏览器端能识别的html,也就是相当于浏览器登陆
            response.getWriter().write(content);

    }



    private String getPageCache() {
        return (String) ehCacheObjectDataUtil.getData(CacheConstants.CACHE_PUBLIC_PERSON,CacheConstants.KEY_PUBLIC_PERSON);
    }

    private void setPageCache(String content) {
        log.info(content);
        ehCacheObjectDataUtil.setData(CacheConstants.CACHE_PUBLIC_PERSON, CacheConstants.KEY_PUBLIC_PERSON,content);
    }

    /**
     * 刷新页面
     */
    @RequestMapping("/h5/refurbish")
    @ResponseBody
    public boolean refurbishCache() {
        return  ehCacheObjectDataUtil.delete(CacheConstants.CACHE_PUBLIC_PERSON, CacheConstants.KEY_PUBLIC_PERSON);
    }



}

1.1.4、如果是使用的单点登录,登录之后可能不会直接访问到域名,而是后缀加的jsessionid,所以要去掉,springBoot启动main中添加如下

public class AdminApplication  extends SpringBootServletInitializer implements CommandLineRunner {


    public static void main(String[] args) {
        SpringApplication.run(AdminApplication.class, args);
    }

        //继承SpringBootServletInitializer 解决单点登录之后,请求头中出现 的jsesssionid 不能正常跳转到前端域名的问题
        //之前使用的sendRedirect()不管用,也不知道为啥,反正使用下面这种就没错了
        public void onStartup(ServletContext servletContext) throws ServletException {
            super.onStartup(servletContext);

            // This will set to use COOKIE only
            servletContext.setSessionTrackingModes(
                    Collections.singleton(SessionTrackingMode.COOKIE)
            );
            // This will prevent any JS on the page from accessing the
            // cookie - it will only be used/accessed by the HTTP transport
            // mechanism in use
            SessionCookieConfig sessionCookieConfig =
                    servletContext.getSessionCookieConfig();
            sessionCookieConfig.setHttpOnly(true);

        }
    }

2、同一个服务器的前后端分离

2.1、同一个服务器但是子域名不相同,也是跨域。但是这样的就不需要设置上面的IndexController,将前端页面解析下来了。

后端登录后还是去掉jssessionid。这样的话访问的就是简单的域名了,比如,server.healerjean.com,这个时候,我们给它跳转到前端的url去


#服务器登录之后跳转到前端url
server.login.redirect.url=quan.dangqugame.cn


@Value("${server.login.redirect.url}")
private String server_login_redirect_url;
/**
 * 首页面进入之后,跳转到前端url界面,如果是前后端分离用的两个域名的情况下
 * @return
 */
@GetMapping(value = {"/",""} )
public String loginDev(){
    return  "redirect://"+server_login_redirect_url;
}





如果满意,请打赏博主任意金额,感兴趣的在微信转账的时候,添加博主微信哦, 请下方留言吧。可与博主自由讨论哦

支付包 微信 微信公众号
支付宝 微信 微信公众号
posted @ 2018-07-17 17:39  HealerJean  阅读(301)  评论(0编辑  收藏  举报