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 相关文章推荐
使用jQuery+HttpHandler+xml模拟一个三级联动的例子
Aug 09 Javascript
js+css实现增加表单可用性之提示文字
Jun 03 Javascript
javascript特殊用法示例介绍
Nov 29 Javascript
js获取input长度并根据页面宽度设置其大小及居中对齐
Aug 22 Javascript
js判断手机和pc端选择不同执行事件的方法
Jan 30 Javascript
详解javascript高级定时器
Dec 31 Javascript
Javascript中的几种继承方式对比分析
Mar 22 Javascript
Bootstrap文件上传组件之bootstrap fileinput
Nov 25 Javascript
原生Aajax 和jQuery Ajax 写法个人总结
Mar 24 jQuery
利用node.js制作命令行工具方法教程(一)
Jun 22 Javascript
基于JS实现table导出Excel并保留样式
May 19 Javascript
基于javascript原生判断DOM是否加载完毕
Oct 14 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
PHILIPS AE3805收音机的分析打磨
2021/03/02 无线电
用PHP实现小写金额转换大写金额的代码(精确到分)
2012/01/10 PHP
php+js实现图片的上传、裁剪、预览、提交示例
2013/08/27 PHP
PHP获取指定时间段之间的 年,月,天,时,分,秒
2016/06/05 PHP
PHP实现基本留言板功能原理与步骤详解
2020/03/26 PHP
如何在标题栏显示框架内页面的标题
2007/02/03 Javascript
Javascript WebSocket使用实例介绍(简明入门教程)
2014/04/16 Javascript
jQuery中:radio选择器用法实例
2015/01/03 Javascript
Jquery使用val方法读写value值
2015/05/18 Javascript
js获取页面description的方法
2015/05/21 Javascript
jquery实现左右滑动菜单效果代码
2015/08/27 Javascript
关于javascript中限定时间内防止按钮重复点击的思路详解
2016/08/16 Javascript
详解微信小程序开发—你期待的分享功能来了,微信小程序序新增5大功能
2016/12/23 Javascript
Angularjs根据json文件动态生成路由状态的实现方法
2017/04/17 Javascript
你可能不知道的CORS跨域资源共享
2019/03/13 Javascript
vue循环数组改变点击文字的颜色
2019/10/14 Javascript
Vue实现导航栏的显示开关控制
2019/11/01 Javascript
python使用in操作符时元组和数组的区别分析
2015/05/19 Python
Python实现快速排序算法及去重的快速排序的简单示例
2016/06/26 Python
浅析Git版本控制器使用
2017/12/10 Python
Python 绘图库 Matplotlib 入门教程
2018/04/19 Python
详解Python list和numpy array的存储和读取方法
2019/11/06 Python
Python中求对数方法总结
2020/03/10 Python
解决django xadmin主题不显示和只显示bootstrap2的问题
2020/03/30 Python
基于HTML5+CSS3实现简单的时钟效果
2017/09/11 HTML / CSS
应届行政管理专业个人自我评价
2013/12/28 职场文书
面试后的感谢信范文
2014/02/01 职场文书
预备党员公开承诺书
2014/05/28 职场文书
机械电子工程专业自荐书
2014/06/10 职场文书
护士节演讲稿开场白
2014/08/25 职场文书
通知函的格式
2015/04/27 职场文书
2016年先进教师个人事迹材料
2016/02/26 职场文书
2016年小学教师师德承诺书
2016/03/25 职场文书
Python代码,能玩30多款童年游戏!这些有几个是你玩过的
2021/04/27 Python
python的变量和简单数字类型详解
2021/09/15 Python
SQL Server使用T-SQL语句批处理
2022/05/20 SQL Server