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脚本
Dec 03 Javascript
上传文件返回的json数据会被提示下载问题解决方案
Dec 03 Javascript
javascript实现客户端兼容各浏览器创建csv并下载的方法
Mar 23 Javascript
IE6-IE9使用JSON、table.innerHTML所引发的问题
Dec 22 Javascript
jQuery Ajax传值到Servlet出现乱码问题的解决方法
Oct 09 Javascript
AngularJS实现根据变量改变动态加载模板的方法
Nov 04 Javascript
Vue.js开发环境快速搭建教程
Mar 17 Javascript
微信小程序商品详情页的底部弹出框效果
Nov 16 Javascript
微信小程序项目实践之验证码倒计时功能
Jul 18 Javascript
从源码里了解vue中的nextTick的使用
Nov 22 Javascript
vue的滚动条插件实现代码
Sep 07 Javascript
JS获取一个字符串中指定字符串第n次出现的位置
Feb 10 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&amp;&amp;mysql)一
2006/10/09 PHP
PHP stristr() 函数(不区分大小写的字符串查找)
2010/06/03 PHP
php中获取关键词及所属来源搜索引擎名称的代码
2011/02/15 PHP
PHP 动态生成静态HTML页面示例代码
2014/01/15 PHP
php 创建以UNIX时间戳命名的文件夹(示例代码)
2014/03/08 PHP
php查询mssql出现乱码的解决方法
2014/12/29 PHP
php阿拉伯数字转中文人民币大写
2015/12/21 PHP
从性能方面考虑PHP下载远程文件的3种方法
2015/12/29 PHP
PHP集成环境XAMPP的安装与配置
2018/11/13 PHP
jquery中的sortable排序之后的保存状态的解决方法
2010/01/28 Javascript
javascript 词法作用域和闭包分析说明
2010/08/12 Javascript
Js控制滑轮左右滑动实例
2015/02/13 Javascript
javascript中replace( )方法的使用
2015/04/24 Javascript
js表单提交和submit提交的区别实例分析
2015/12/10 Javascript
jQuery基于ID调用指定iframe页面内的方法
2016/07/06 Javascript
vue + socket.io实现一个简易聊天室示例代码
2017/03/06 Javascript
使用jQuery监听扫码枪输入并禁止手动输入的实现方法(推荐)
2017/03/21 jQuery
微信小程序动态的加载数据实例代码
2017/04/14 Javascript
Angular通过指令动态添加组件问题
2018/07/09 Javascript
layer弹出层父子页面事件相互调用方法
2018/08/17 Javascript
echarts大屏字体自适应的方法步骤
2019/07/12 Javascript
uni-app实现点赞评论功能
2019/11/25 Javascript
原生js+ajax分页组件
2020/01/30 Javascript
手把手教您实现react异步加载高阶组件
2020/04/07 Javascript
何时/使用 Vue3 render 函数的教程详解
2020/07/25 Javascript
详解Python中__str__和__repr__方法的区别
2015/04/17 Python
python执行scp命令拷贝文件及文件夹到远程主机的目录方法
2019/07/08 Python
Django model重写save方法及update踩坑详解
2020/07/27 Python
python中remove函数的踩坑记录
2021/01/04 Python
使用CSS实现阅读进度条
2017/02/27 HTML / CSS
澳大利亚领先的武术用品和健身器材供应商:SMAI
2019/03/24 全球购物
销售文员岗位职责
2013/11/29 职场文书
单位领导证婚词
2014/01/14 职场文书
学校安全工作制度
2014/01/19 职场文书
党的群众路线教育实践活动个人承诺书
2014/05/22 职场文书
检讨书范文1000字
2015/01/28 职场文书