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中对表单的基本操作代码
Jul 29 Javascript
jQuery基于ajax()使用serialize()提交form数据的方法
Dec 08 Javascript
jQuery EasyUI编辑DataGrid用combobox实现多级联动
Aug 29 Javascript
Node.js开启Https的实践详解
Oct 25 Javascript
jquery滚动条插件(可以自定义)
Dec 11 Javascript
jQuery点击导航栏选中更换样式的实现代码
Jan 23 Javascript
canvas实现粒子时钟效果
Feb 06 Javascript
利用Bootstrap Multiselect实现下拉框多选功能
Apr 08 Javascript
Vue封装的组件全局注册并引用
Jul 24 Javascript
Js图片点击切换轮播实现代码
Jul 27 Javascript
vue打包npm run build时候界面报错的解决
Aug 13 Javascript
微信小程序将页面按钮悬浮固定在底部的实现代码
Oct 29 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获取php,mysql,apche的版本信息示例代码
2014/01/16 PHP
php像数组一样存取和修改字符串字符
2014/03/21 PHP
基于PHP+jQuery+MySql实现红蓝(顶踩)投票代码
2015/08/25 PHP
PHP编程快速实现数组去重的方法详解
2017/07/22 PHP
php 使用expat方式解析xml文件操作示例
2019/11/26 PHP
php经典趣味算法实例代码
2020/01/21 PHP
PHP设计模式(四)原型模式Prototype实例详解【创建型】
2020/05/02 PHP
JavaScript 关键字屏蔽实现函数
2009/08/02 Javascript
JQuery模板插件 jquery.tmpl 动态ajax扩展
2011/11/10 Javascript
详解JavaScript操作HTML DOM的基本方式
2015/10/21 Javascript
浅谈javascript中的加减时间
2016/07/12 Javascript
jQuery通过ajax方法获取json数据不执行success的原因及解决方法
2016/10/15 Javascript
详解Bootstrap各式各样的按钮(推荐)
2016/12/13 Javascript
Angular自定义组件实现数据双向数据绑定的实例
2017/12/11 Javascript
vue+jquery+lodash实现滑动时顶部悬浮固定效果
2018/04/28 jQuery
详解项目升级到vue-cli3的正确姿势
2019/01/28 Javascript
浅谈TypeScript的类型保护机制
2020/02/23 Javascript
Vue axios与Go Frame后端框架的Options请求跨域问题详解
2020/03/03 Javascript
js实现贪吃蛇游戏 canvas绘制地图
2020/09/09 Javascript
[48:48]2014 DOTA2国际邀请赛中国区预选赛 SPD-GAMING VS Dream TIME
2014/05/21 DOTA
[46:25]DOTA2上海特级锦标赛主赛事日 - 4 败者组第五轮 MVP.Phx VS EG第二局
2016/03/05 DOTA
[01:47]2018年度DOTA2最佳教练-完美盛典
2018/12/16 DOTA
python处理html转义字符的方法详解
2016/07/01 Python
python2.7读取文件夹下所有文件名称及内容的方法
2018/02/24 Python
对Python中DataFrame按照行遍历的方法
2018/04/08 Python
浅谈Python中threading join和setDaemon用法及区别说明
2020/05/02 Python
在tensorflow下利用plt画论文中loss,acc等曲线图实例
2020/06/15 Python
英国最受欢迎的平价女士时装零售商:Roman Originals
2019/11/02 全球购物
编程用JAVA解析XML的方式
2013/07/07 面试题
聚美优品励志广告词
2014/03/14 职场文书
新年团拜会主持词
2014/04/02 职场文书
企业公益活动策划方案
2014/08/24 职场文书
中国世界遗产导游词
2015/02/13 职场文书
可可西里观后感
2015/06/08 职场文书
JavaWeb Servlet开发注册页面实例
2022/04/11 Java/Android
TS 类型收窄教程示例详解
2022/09/23 Javascript