Next.js项目实战踩坑指南(笔记)


Posted in Javascript onNovember 29, 2018

前言

github: https://github.com/code-coder/next-mobile-complete-app

已经用Next.js快两个月了,项目已经提测了,这里总结一下开发过程中,以及在部署的时候遇到一些棘手的问题。

疑难杂症

1. 移动端overflow:auto,ios滚动卡顿

解决方案: 主容器增加样式-webkit-overflow-scrolling: touch;

2. dev mode路由跳转后样式丢失

原因:dev下样式根据页面动态加载,浏览器缓存文件styles.chunk.css造成样式不更新。

解决方案: 利用版本号强制重载样式文件

示例1:

// 在Layout组件中
<Head>
  <title>{title}</title>
  {process.env.NODE_ENV !== 'production' && (<link rel="stylesheet" type="text/css" href={'/_next/static/css/styles.chunk.css?v=' + Router.route} />)}
</Head>

示例2:

// 在_app.js中
import Router from 'next/router';

Router.events.on('routeChangeComplete', () => {
 if (process.env.NODE_ENV !== 'production') {
  const els = document.querySelectorAll('link[href*="/_next/static/css/styles.chunk.css"]');
  const timestamp = new Date().valueOf();
  els[0].href = '/_next/static/css/styles.chunk.css?v=' + timestamp;
 }
});

3、Android 键盘弹起窗口会变小,有 flex 或者 position 是 absolute 或者 fixed 布局会变

这里直接把body.height设置为浏览器的窗口高度。

doc.body.style.height = docEl.clientHeight + 'px';

4、跨域及传递cookie的问题

第一步,登录成功后api服务器返回cookie。

跨域访问要接收cookie,解决办法也很简单只需要API服务器根据请求地址设置Access-Control-Allow-Origin的值为请求地址的ip就可以了(测试环境可以动态设置这个ip,生产可以设置指定的域名或者ip地址)。

第二步,浏览器自动缓存,再后续请求中携带此cookie。

fetch或axois请求都默认不带cookie,需要通过option配置打开。

- fetch要配置`{ credentials: 'include', mode: 'cors' }`

- axois要配置`axios.defaults.withCredentials=true;`

另外,还可以通过服务器代理走内网访问api。

以下为我们公司所采用的解决方案:

为了解决跨域以及部署不同服务器需要修改 api 地址的问题,我们使用 前端服务器代理 + dns 解析。整个流程如下图所示:

Next.js项目实战踩坑指南(笔记)

通过NODE_ENV环境变量来配置开发和生产的地址。

const isProd = process.env.NODE_ENV === 'production';
process.env.BACKEND_URL = isProd ? '/relative_url' : 'http://text.api.com';
process.env.BACKEND_URL_SERVER_SIDE = isProd ? 'http://bff.api.com' : 'https://prod.api.com';

module.exports = {
 'process.env.BACKEND_URL': process.env.BACKEND_URL, // 客户端渲染请求,是个相对地址,在前端服务器被代理到API服务器
 'process.env.BACKEND_URL_SERVER_SIDE': process.env.BACKEND_URL_SERVER_SIDE // 服务端渲染请求,是API服务器地址,仅供内网访问
};

5、服务端渲染时带 cookie 请求的问题

这里用到一个插件叫nookies。

在_app.js中全局解析cookies注入ctx:

static async getInitialProps({ Component, ctx }) {
  let pageProps = {};

  let cookies = {};
  if (ctx.isServer) {
   cookies = parseCookies(ctx);
  }
  if (Component.getInitialProps) {
   pageProps = await Component.getInitialProps({ ctx, cookies });
  }

  return { pageProps };
 }

然后就可以通过页面请求:

static async getInitialProps({ ctx }) {
  const { store, req, isServer, cookies } = ctx;
  store.dispatch(setNav({ navTitle: 'Home', isHome: true }));
  store.dispatch(getDataStart({ settings: { isServer, cookies } }));
 }

proxyFetch中就会根据isServer的值来分辨是服务端API请求还是客户端API请求。服务端请求会把cookies写入Fetch的header中。

const prefix = isServer ? process.env.BACKEND_URL_SERVER_SIDE : process.env.BACKEND_URL;
isServer && (this.headers['cookie'] = 'EGG_SESS=' + cookies['EGG_SESS'] + ';';)
// fetch核心
fetch(prefix + url, { headers: this.headers, ...this.init, ...options })

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
js正则表达式匹配数字字母下划线等
Apr 14 Javascript
Adapter适配器模式在JavaScript设计模式编程中的运用分析
May 18 Javascript
JS获取随机数和时间转换的简单实例
Jul 10 Javascript
js 中获取制定的cook信息实现方法
Nov 19 Javascript
浅谈vue路径优化之resolve
Oct 13 Javascript
JS简单添加元素新节点的方法示例
Feb 10 Javascript
vue element-ui 绑定@keyup事件无效的解决方法
Mar 09 Javascript
vue.js通过路由实现经典的三栏布局实例代码
Jul 08 Javascript
JavaScript学习笔记之图片库案例分析
Jan 08 Javascript
Vue核心概念Action的总结
Jan 18 Javascript
详解js动态获取浏览器或页面等容器的宽高
Mar 13 Javascript
js实现贪吃蛇游戏 canvas绘制地图
Sep 09 Javascript
js canvas实现二维码和图片合成的海报
Nov 19 #Javascript
详解@angular/cli 改变默认启动端口两种方式
Nov 29 #Javascript
js实现每日签到功能
Nov 29 #Javascript
Vue.js的复用组件开发流程完整记录
Nov 29 #Javascript
javascript实现考勤日历功能
Nov 29 #Javascript
vsCode安装使用教程和插件安装方法
Aug 24 #Javascript
vue 右键菜单插件 简单、可扩展、样式自定义的右键菜单
Nov 29 #Javascript
You might like
有关PHP性能优化的介绍
2013/06/20 PHP
wordpress自定义url参数实现路由功能的代码示例
2013/11/28 PHP
百度实时推送api接口应用示例
2014/10/21 PHP
PHP结合jQuery插件ajaxFileUpload实现异步上传文件实例
2020/08/17 PHP
PHP实现表单提交数据的验证处理功能【防SQL注入和XSS攻击等】
2017/07/21 PHP
Yii2框架实现利用mpdf创建pdf文件功能示例
2019/02/08 PHP
extjs 列表框(multiselect)的动态添加列表项的方法
2009/07/31 Javascript
JavaScript replace(rgExp,fn)正则替换的用法
2010/03/04 Javascript
用JS做的简单的可折叠的两级树形菜单
2013/09/21 Javascript
react native带索引的城市列表组件的实例代码
2017/08/08 Javascript
基于jQuery实现图片推拉门动画效果的两种方法
2017/08/26 jQuery
Vue Element 分组+多选+可搜索Select选择器实现示例
2018/07/23 Javascript
你可能不知道的CORS跨域资源共享
2019/03/13 Javascript
小程序实现悬浮搜索框
2019/07/12 Javascript
JavaScript如何使用插值实现图像渐变
2020/06/28 Javascript
详解React 元素渲染
2020/07/07 Javascript
在Python中操作字典之update()方法的使用
2015/05/22 Python
Python实现将数据库一键导出为Excel表格的实例
2016/12/30 Python
Python连接数据库学习之DB-API详解
2017/02/07 Python
python切片及sys.argv[]用法详解
2018/05/25 Python
python 实现提取某个索引中某个时间段的数据方法
2019/02/01 Python
python 字典有序并写入json文件过程解析
2019/09/30 Python
python实现全排列代码(回溯、深度优先搜索)
2020/02/26 Python
python 日志 logging模块详细解析
2020/03/31 Python
Django {{ MEDIA_URL }}无法显示图片的解决方式
2020/04/07 Python
python中shell执行知识点
2020/05/06 Python
HTML5 MiranaVideo播放器 (代码开源)
2010/06/11 HTML / CSS
全天然狗零食:Best Bully Sticks
2016/09/22 全球购物
军校制空专业毕业生自我鉴定
2013/11/16 职场文书
房屋买卖协议书范本
2014/04/10 职场文书
小学班主任评语大全
2014/04/23 职场文书
个性婚礼策划方案
2014/05/17 职场文书
公司副总经理岗位职责
2014/10/01 职场文书
运动会广播稿200字(10篇)
2014/10/12 职场文书
优秀班主任工作总结2015
2015/05/25 职场文书
使用php的mail()函数实现发送邮件功能
2021/06/03 PHP