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和css代码压缩工具[附JAVA环境配置方法]
Apr 16 Javascript
jquery随机展示头像代码
Dec 21 Javascript
ANT 压缩(去掉空格/注释)JS文件可提高js运行速度
Apr 15 Javascript
javascript 树形导航菜单实例代码
Aug 13 Javascript
Javascript小技巧之生成html元素
May 15 Javascript
在Node.js中使用HTTP上传文件的方法
Jun 23 Javascript
JQuery实现简单的图片滑动切换特效
Nov 22 Javascript
使用angularjs创建简单表格
Jan 21 Javascript
几种二级联动案例(jQuery\Array\Ajax php)
Aug 13 Javascript
jQuery ajax 当async为false时解决同步操作失败的问题
Nov 18 Javascript
vue2.0中set添加属性后视图不能更新的解决办法
Feb 22 Javascript
微信小程序学习笔记之目录结构、基本配置图文详解
Mar 28 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与MySQL开发的8个技巧小结
2010/12/17 PHP
CI(CodeIgniter)框架中的增删改查操作
2014/06/10 PHP
PHP自毁程序(慎用)
2015/07/09 PHP
PHP实现四种基础排序算法的运行时间比较(推荐)
2016/08/11 PHP
php版微信公众平台开发之验证步骤实例详解
2016/09/23 PHP
Laravel6.2中用于用户登录的新密码确认流程详解
2019/10/16 PHP
javascript常用方法、属性集合及NodeList 和 HTMLCollection 的浏览器差异
2010/12/25 Javascript
formvalidator验证插件中有关ajax验证问题
2013/01/04 Javascript
用js写了一个类似php的print_r输出换行功能
2013/02/18 Javascript
js字符串日期yyyy-MM-dd转化为date示例代码
2014/03/06 Javascript
js图片预加载示例
2014/04/30 Javascript
firefox浏览器用jquery.uploadify插件上传时报HTTP 302错误
2015/03/01 Javascript
jQuery标签编辑插件Tagit使用指南
2015/04/21 Javascript
jQuery控制frames及frame页面JS的方法
2016/03/08 Javascript
jquery显示隐藏元素的实现代码
2016/05/19 Javascript
Bootstrap前端开发案例二
2016/06/17 Javascript
前端弹出对话框 js实现ajax交互
2016/09/09 Javascript
JavaScript求一组数的最小公倍数和最大公约数常用算法详解【面向对象,回归迭代和循环】
2018/05/07 Javascript
JS开发 富文本编辑器TinyMCE详解
2019/07/19 Javascript
Vue+Typescript中在Vue上挂载axios使用时报错问题
2019/08/07 Javascript
浅析JavaScript预编译和暗示全局变量
2020/09/03 Javascript
[28:42]Ti4正赛VG vs NEWBEE1
2014/07/19 DOTA
[00:42]《辉夜杯》—职业组预选赛12月3日15点 正式打响
2015/12/03 DOTA
跟老齐学Python之玩转字符串(2)
2014/09/14 Python
以Flask为例讲解Python的框架的使用方法
2015/04/29 Python
python 中if else 语句的作用及示例代码
2018/03/05 Python
python3应用windows api对后台程序窗口及桌面截图并保存的方法
2019/08/27 Python
Python类如何定义私有变量
2020/02/03 Python
python 伯努利分布详解
2020/02/25 Python
广告学专业自荐信范文
2014/02/24 职场文书
三分钟自我介绍演讲稿
2014/08/21 职场文书
2014基建处领导班子“四风”对照检查材料思想汇报
2014/10/04 职场文书
高中教师个人工作总结
2015/02/10 职场文书
2015年重阳节主持词
2015/07/04 职场文书
Oracle 区块链表创建过程详解
2021/05/15 Oracle
Android基础入门之dataBinding的简单使用教程
2022/06/21 Java/Android