vue + CI + APACHE 前后端分离服务器部署踩坑(vue-cli-3)

vue + CI + APACHE 前后端分离服务器部署踩坑(vue-cli-3),第1张

1.前端本地开发环境需要配置代理:

在项目路径下创建 vue.config.js ,内容如下:

const path = require('path')

module.exports = {

// publicPath:'http:// .com/mm',// 线上

publicPath:'', //本地

outputDir: process.env.NODE_ENV === "development" ? 'devdist' : 'dist', // 不同的环境打不同包名

devServer:{ // 配置服务器

port:8891,

open:true,

https:false,

// disableHostCheck: true,

overlay: {

warnings: true,

errors: true

},

proxy:{ //主要是这里,设置代理!!!!

'/api': {

target: ' http://www . .com:****',

changeOrigin: true,

ws: true,

pathRewrite: {

'^/api': ''

}

}

}

},

configureWebpack:{ // 覆盖webpack默认配置的都在这里

resolve:{ // 配置解析别名

alias:{

'@':path.resolve(__dirname, './src'),

'@a':path.resolve(__dirname, './src/api'),

'@f':path.resolve(__dirname, './src/filters'),

'@u':path.resolve(__dirname, './src/utils'),

}

}

}

}

2.设置完代理之后可以请求url直接用 : '/api/' + *** 代替

3.如果前端的路由是‘history’模式,则需要在部署服务器时,在index.html同路劲下新增文件 : .htaccess, 内容如下:

<IfModule mod_rewrite.c>

RewriteEngine On

RewriteBase /

RewriteRule ^index.html$ - [L]

RewriteCond %{REQUEST_FILENAME} !-f

RewriteCond %{REQUEST_FILENAME} !-d

RewriteRule . /index.html [L]

</IfModule>

主要是为了刷新的时候,路由重写到 index.html下面。

作者:关开发

一.什么是前后端分离?

理解前后端分离大概可以从3个方面理解:

1. 交互形式

2. 代码组织形式

3. 开发模式与流程

1.1 交互形式

前后端不分离

后端将数据和页面组装、渲染好了之后,向浏览器输出最终的html;浏览器接收到后会解析html,解析引入的css、执行js脚本,完成最终的页面展示。

前后端分离

后端只需要和前端约定好接收以及返回的数据格式(一般用JSON格式),向前端提供API接口。前端就可以通过HTTP请求调用API的方式进行交互。前端获取到数据后,进行页面组装、渲染,最终在浏览器呈现。

1.2 代码组织形式

前后端不分离

在web应用早期的时候,前端页面以及后台业务数据处理的代码都放在一个工程下,甚至放在同一目录下,前端页面夹杂着后端代码。前、后端开发工程师都需要把整套代码导入开发工具才能开发。此阶段下前后端代码以及工作耦合度太高,前端不能独立开发和测试,后端人员也要依赖前端完成页面后才能完成开发。最糟糕的情况是前端工程师需要会后端模板技术(jsp),后端工程师还要会点前端技术,需要口头说明页面数据接口,才能配合完成开发。否则前端只能当一个“切图仔”,只输出HTML、CSS、以及很少量与业务逻辑无关的js;然后由后端转化为后端jsp,并且还要写业务的js代码。

前后端分离

前后端代码放在不同的工程下,前端代码可以独立开发,通过mock/easy-mock技术模拟后端API服务可以独立运行、测试;后端代码也可以独立开发,运行、测试,通过swagger技术能自动生成API文档供前端阅读,还可以进行自动化接口测试,保证API的可用性,降低集成风险。

1.3 开发模式与流程

前后端不分离

在项目开发阶段,前端根据原型和UI设计稿,编写HTML、CSS以及少量与业务无关的js(纯效果那些),完成后交给后台人员,后台人员将HTML转为jsp,并通过JSP的模板语法进行数据绑定以及一些逻辑操作。后台完成后,将全部代码打包,包含前端代码、后端代码打成一个war,然后部署到同一台服务器运行。顶多做一下动静分离,也就是把图片、css、js分开部署到nginx。

具体开发流程如下:图略

前后端分离

实现前后端分离之后,前端根据原型和UI设计稿编写HTML、CSS以及少量与业务无关的js(纯效果那些),后端也同时根据原型进行API设计,并与前端协定API数据规范。等到后台API完成,或仅仅是API数据规范设定完成之后。前端即可通过HTTP调用API,或通过mock数据完成数据组装以及业务逻辑编写。前后端可以并行,或者前端先行于后端开发了。

具体开发流程如下:图略

二、前后端分离的好处与坏处。

从上面3个方面对比了之后,前后端分离架构和传统的web架构相比,有很大的变化,看起来好处多多。到底是分还是不分,我们还是要理性分析是否值得才去做。

从目前应用软件开发的发展趋势来看,主要有两方面需要注意:

· 越来越注重用户体验,随着互联网的发展,开始多终端化。

· 大型应用架构模式正在向云化、微服务化发展。

我们主要通过前后端分离架构,为我们带来以下四个方面的提升:

· 为优质产品打造精益团队

通过将开发团队前后端分离化,让前后端工程师只需要专注于前端或后端的开发工作,是的前后端工程师实现自治,培养其独特的技术特性,然后构建出一个全栈式的精益开发团队。

· 提升开发效率

前后端分离以后,可以实现前后端代码的解耦,只要前后端沟通约定好应用所需接口以及接口参数,便可以开始并行开发,无需等待对方的开发工作结束。与此同时,即使需求发生变更,只要接口与数据格式不变,后端开发人员就不需要修改代码,只要前端进行变动即可。如此一来整个应用的开发效率必然会有质的提升。

· 完美应对复杂多变的前端需求

如果开发团队能完成前后端分离的转型,打造优秀的前后端团队,开发独立化,让开发人员做到专注专精,开发能力必然会有所提升,能够完美应对各种复杂多变的前端需求。

· 增强代码可维护性

前后端分离后,应用的代码不再是前后端混合,只有在运行期才会有调用依赖关系。应用代码将会变得整洁清晰,不论是代码阅读还是代码维护都会比以前轻松。

那么前后端分离有什么不好的地方吗?我目前是没有想到,除非你说会增加前端团队的配备,后端工程师会变的不全能。。。

二、前后端分离架构方案。

实现前后端分离,主要是前端的技术架构变化较大,后端主要变为restfull 风格API,然后加上Swagger技术自动生成在线接口文档就差不多了。

对于目前用于前后端分离方案的前端技术架构主要有两种:

· 传统SPA

· 服务端渲染SSR

2.1 传统SPA

传统SPA指的是单页面应用,也就是整个网站只有一个页面,所有功能都通过这一个页面来呈现。因为一个人的肉眼,某一个时间点看一个页面,既然如此何必要不同功能做多个页面呢?只保留一个页面作为模板,然后通过路由跳转来更新这个模板页面的内容不就可以了吗?确实如此,现在通过reac全家桶、tvue全家桶,模块化、路由、wabpack等技术轻而易举就能实现一个单页面应用。

单页面应用的运行流程

1.用户通过浏览器访问网站url

2.单页面的html文件(index.html)被下载到浏览器,接着下载html里面引用的css,js。

3.css,js下载到浏览器完成之后,浏览器开始解析执行js向后端服务异步请求数据。

4.请求数据完成后,进行数据绑定、渲染,最终在用户浏览器呈现完整的页面。

2.2 服务端渲染

服务端渲染的方案指的是数据绑定,渲染等工作都放在服务端完成,服务端向浏览器输出最终的html。大家看完这个是不是有个疑问,这不是又回到了前后端不分离的时代了吗?答案是否定的,因为这里的服务端是用来执行前端数据绑定、渲染的,也就是把浏览器的一部分工作分担到了服务端。而目前具备这只种能力的服务端是NodeJs服务端。

它的原理其实就是在浏览器与前端代码中间插入了一个NodeJs服务端。浏览器请求前端页面时,会先经过NodeJS服务端,由NodeJs去读取前端页面,并执行异步后端API,获取到数据后进行页面数据绑定,渲染等工作,完成一个最终的html然后返回浏览器,最后浏览器进行展示。

服务端渲染应用的运行流程:

1.用户通过浏览器访问网站url

2.NodeJS服务端接收到请求,读取到对应的前端html,css,js。

3.NodeJS解析执行js向后端API异步请求数据。

4.NodeJs请求数据完成之后,进行数据绑定、渲染,得到一个最终的html。

5.NodeJs向浏览器输出html,浏览器进行展示。

PS:其实本质就是把前端编写成一个nodeJs的服务端web应用。实施服务端渲染后,我们最终运行的是一个Nodejs服务端应用。而单页面应用是把静态页面部署到静态资源服务器进行运行。

看到这里,你是否又有疑问,为什么要这么麻烦搞服务端渲染呢?

2.3 SPA与服务端渲染方案对比

SPA的优点是开发简单,部署简单;缺点是首次加载较慢,需要较好的网络,不友好的SEO。

so,以下就是使用服务端渲染的理由了(摘取vue官方说法):

与传统 SPA (单页应用程序 (Single-Page Application)) 相比,服务器端渲染 (SSR) 的优势主要在于:

· 更好的 SEO,由于搜索引擎爬虫抓取工具可以直接查看完全渲染的页面。

请注意,截至目前,Google 和 Bing 可以很好对同步 JavaScript 应用程序进行索引。在这里,同步是关键。如果你的应用程序初始展示 loading 菊花图,然后通过 Ajax 获取内容,抓取工具并不会等待异步完成后再行抓取页面内容。也就是说,如果 SEO 对你的站点至关重要,而你的页面又是异步获取内容,则你可能需要服务器端渲染(SSR)解决此问题。

· 更快的内容到达时间 (time-to-content),特别是对于缓慢的网络情况或运行缓慢的设备。

无需等待所有的 JavaScript 都完成下载并执行,才显示服务器渲染的标记,所以你的用户将会更快速地看到完整渲染的页面。通常可以产生更好的用户体验,并且对于那些「内容到达时间(time-to-content) 与转化率直接相关」的应用程序而言,服务器端渲染 (SSR) 至关重要。

使用服务器端渲染 (SSR) 时还需要有一些权衡之处:

· 开发条件所限。浏览器特定的代码,只能在某些生命周期钩子函数 (lifecycle hook) 中使用;一些外部扩展库 (external library) 可能需要特殊处理,才能在服务器渲染应用程序中运行。

· 涉及构建设置和部署的更多要求。与可以部署在任何静态文件服务器上的完全静态单页面应用程序 (SPA) 不同,服务器渲染应用程序,需要处于 Node.js server 运行环境。

· 更多的服务器端负载。在 Node.js 中渲染完整的应用程序,显然会比仅仅提供静态文件的 server 更加大量占用 CPU 资源 (CPU-intensive - CPU 密集),因此如果你预料在高流量环境 (high traffic) 下使用,请准备相应的服务器负载,并明智地采用缓存策略。

以vue为例,实施服务端渲染可以查看官方指南: https://ssr.vuejs.org ,或选择Nuxt.js

2.4 预渲染技术

如果你调研服务器端渲染 (SSR) 只是用来改善少数营销页面(例如 /, /about, /contact 等)的 SEO,那么你可能需要预渲染。无需使用 web 服务器实时动态编译 HTML,而是使用预渲染方式,在构建时 (build time) 简单地生成针对特定路由的静态 HTML 文件。优点是设置预渲染更简单,并可以将你的前端作为一个完全静态的站点。

如果你使用 webpack,你可以使用 prerender-spa-plugin 轻松地添加预渲染。它已经被 Vue 应用程序广泛测试 - 事实上,作者是 Vue 核心团队的成员。

prerender-spa-plugin: https://github.com/chrisvfritz/prerender-spa-plugin

三、前后端分离技术选型

- artTemplate + bootstrap(不推荐, 不算完全前后端分离)

- vue全家桶(推荐)

- react全家桶 (推荐,生态全)

在前后端分离架构下,难免会遇到跨域问题。但是对于跨域,很多人并没有多么深入的了解。这里我就详细讲一下这个问题。

同源策略与跨域

所谓跨域,英文叫做cross-domain,是网络安全领域的一个专有名词。简单点理解就是某些操作越过了域名的界限,访问了别的域名。

如果脚本可以自由访问其他域,就会产生很多安全问题。

比如,假设有一个网上银行系统,你已经登录过了,它支持一个ajax api可以进行转账;有一个论坛系统,人气很高,但是其中有恶意脚本,这个脚本会调用这个ajax api,从当前登录的用户账户中,转1000块到攻击者的账户。这样,当你访问这个论坛的时候,就会被转走1000块,而你一点都不知道!

除此之外,跨域请求还有很多危害。这不是一本关于安全的书,也就不展开讲了,想深入了解的可以买一本余弦编写的《Web前端黑客技术揭秘》。

为了防范跨域攻击,所有现代浏览器都遵循一套同源策略。根据MDN上的定义,“如果两个页面拥有相同的协议(protocol),端口(如果指定),和主机,那么这两个页面就属于同一个源(origin)”。对于违反同源策略的请求,除了img src等少数嵌入操作之外,都会被浏览器阻止。

这里需要注意的是:同源不仅仅要求相同的域名或ip,连协议和端口也必须相同。比如https://localhost和http://localhost或http://localhost:3000就不是同源的,而http://localhost/api和http://localhost/views是同源的。

我们平常所说的“跨域”其实就是指“发起不同源请求”,而这样的跨域请求会被浏览器阻止。

同源策略对保障互联网安全有着非常重要的作用,很多安全策略都是基于同源策略的。但是,这种同源策略会对前后端分离架构下的开发过程带来很大困扰。比如,即使是本地服务器,也没法和前端开发服务器运行在同一个端口上,这时候,跨域是必然的。而如果要让后端程序同时提供web服务,则很难发挥前端工具链的轻量级优势。那么,如何解决跨域问题呢?

如何解决跨域问题?

JSONP方式

最初用来解决跨域问题的方式,叫做JSONP,它的基本原理是:跨域的“资源嵌入”是被浏览器允许的。所以,可以通过一个script标签来嵌入一段来自其他服务器的脚本。由于这个脚本完全运行在当前域,无法访问第三方服务器的cookie等敏感信息,所以是安全的。

JSONP的缺点是它只能支持GET操作,没法支持POST等操作,但是由于兼容性好等优点,仍然有很多网站采用JSONP的方式公开自己的API供第三方调用。

在Angular中,$http内置了对JSONP的支持,它的调用接口也和其他方法没什么区别,使用起来非常简单。

反向代理方式

要想解决跨域问题,最简单彻底的方法当然是把他们拉到一个域下,而这就是该“反向代理”发挥作用的时候了。

所谓反向代理,就是在自己的域名下架设一个Web服务器,这个服务器会把请求转发给第三方服务器,然后把结果返回给客户端。

这时候,在客户端看来,自己就是在和这台反向代理服务器打交道,而不知道第三方服务器的存在。

所以,如果有一个Web服务程序,它同时提供了反向代理功能和静态文件服务功能,静态文件服务负责渲染前端页面,反向代理则提供对第三方服务器的透明访问。那么前端和后端就变成了同源的,不再受同源策略的约束。

那么,有这样的Web服务程序吗?有,而且不止一个。事实上,几乎所有的主流Web服务器都提供了反向代理功能。这里仅以nginx为例来示范反向代理的配置方式,其他Web服务器请搜相应的文档自行研究。

server {

listen 80

server_name your.domain.name

location / {

proxy_pass http://localhost:5000/# 把根路径下的请求转发给前端工具链(如gulp)打开的开发服务器,如果是产品环境,则使用root等指令配置为静态文件服务器

}

location /api/ {

proxy_pass http://localhost:8080/service/# 吧 /api 路径下的请求转发给真正的后端服务器

proxy_set_header Host $http_host  # 把host头传过去,后端服务程序将收到your.domain.name,否则收到的是localhost:8080

proxy_cookie_path /api /service   # 把cookie中的path部分从/api替换成/service

proxy_cookie_domain localhost:8080 your.domain.name# 把cookie的path部分从localhost:8080替换成your.domain.name

}

}

注意最后这两句话,由于cookie中存在一个path机制,可以对同一个域下的不同子域进行区分。所以,如果后端所使用的路径是/service,而前端使用的路径是/api,那么前端将不能访问后端的cookie,这就导致登录等操作所写入的cookie无法正常传入传出,其表现则是登录始终没有效果。cookie的domain机制也是类似的原理。

现实中的后端服务器,使用path机制的很多,所以这项设置非常实用。

CORS方式

这是W3C提供的另一种跨域方式。作为一项标准的跨域规范,CORS本应该是最值得采用的。 问题在于,老式浏览器不支持CORS,而我们显然还没到可以无视老式浏览器的时候。 所以,只要有可能,就应该优先采用反向代理的方式。

CORS的原理是基于服务方授权的模式,也就是说提供服务的程序要主动通过CORS回应头来声明自己信任哪些源(协议+域名+端口)。 由于得到了服务方的授权,浏览器就可以放行来自这些域的请求了。

参考:http://www.cnblogs.com/mashch/articles/4261448.html

https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_CORS

http://www.tuicool.com/articles/3q2iaqb

前后台分离,nodeJS转发请求实现跨域访问 :http://blog.csdn.net/u011783224/article/details/52214949


欢迎分享,转载请注明来源:夏雨云

原文地址:https://www.xiayuyun.com/zonghe/533084.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-06-24
下一篇2023-06-24

发表评论

登录后才能评论

评论列表(0条)

    保存