亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > JS > 正文

如何讓Nodejs支持H5 History模式(connect-history-api-fallback源碼分析)

2024-05-06 16:51:40
字體:
來源:轉載
供稿:網友

導讀

本文主要是對connect-history-api-fallback庫進行一次源碼分析。connect-history-api-fallback是一個用于支持SPA History路由模式的nodejs庫。閱讀本文前,應對HTML5 History模式有一定程度的了解!

源碼分析

/**  * 前端需要開啟history模式,而后端根據url并不知道前端在請求api還是在請求頁面,如localhost:4200/home這種url,前端理所當然認為“我需要得到html,并跳轉到首頁”,然而后端并不能區分。 * 因此需要一種判斷機制,來使得后端能分析出前端的請求目的。 * connect-history-api-fallback 這個中間件正好幫我們完成了上述分析操作,來看下它是怎么實現的吧! * 第一次把自己的源碼分析思路寫出來,說得不對的地方,請指出! */'use strict';var url = require('url');exports = module.exports = function historyApiFallback(options) { // 接收配置參數 options = options || {}; // 初始化日志管理器 var logger = getLogger(options); // 中間件是要返回一個函數的,函數形參有req, res, next return function(req, res, next) {  var headers = req.headers;  if (req.method !== 'GET') {   // 如果請求方法不是GET類型,說明不需要返回html,那么就調用next(),把請求交給下一個中間件   logger(    'Not rewriting',    req.method,    req.url,    'because the method is not GET.'   );   return next();  } else if (!headers || typeof headers.accept !== 'string') {   // 如果沒有請求頭,或者請求頭中的accept不是字符串,說明不是一個標準的http請求,也不予處理,把請求交給下一個中間件   logger(    'Not rewriting',    req.method,    req.url,    'because the client did not send an HTTP accept header.'   );   return next();  } else if (headers.accept.indexOf('application/json') === 0) {   // 如果客戶端希望得到application/json類型的響應,說明也不是在請求html,也不予處理,把請求交給下一個中間件   logger(    'Not rewriting',    req.method,    req.url,    'because the client prefers JSON.'   );   return next();  } else if (!acceptsHtml(headers.accept, options)) {   // 如果請求頭中不包含配置的Accept或者默認的['text/html', '*/*'],那么說明也不是在請求html,也不予處理,把請求交給下一個中間件   logger(    'Not rewriting',    req.method,    req.url,    'because the client does not accept HTML.'   );   return next();  }  // 走到這里說明是在請求html了,要開始秀操作了  // 首先利用url模塊的parse方法解析下url,會得到一個對象,包括protocol,hash,path, pathname, query, search等字段,類似瀏覽器的location對象  var parsedUrl = url.parse(req.url);  var rewriteTarget;  // 然后得到配置中的rewrites,也就是重定向配置;  // 重定向配置是一個數組,每一項都包含from和to兩個屬性;  // from是用來正則匹配pathname是否需要重定向的;  // to則是重定向的url,to可以是一個字符串,也可以是一個回調方法來返回一個字符串,回調函數接收一個上下文參數context,context包含三個屬性(parsedUrl,match,request)  options.rewrites = options.rewrites || [];  // 遍歷一波重定向配置  for (var i = 0; i < options.rewrites.length; i++) {   var rewrite = options.rewrites[i];   // 利用字符串的match方法去匹配   var match = parsedUrl.pathname.match(rewrite.from);   if (match !== null) {    // 如果match不是null,說明pathname和重定向配置匹配上了    rewriteTarget = evaluateRewriteRule(parsedUrl, match, rewrite.to, req);    if(rewriteTarget.charAt(0) !== '/') {     // 推薦使用/開頭的絕對路徑作為重定向url     logger(      'We recommend using an absolute path for the rewrite target.',      'Received a non-absolute rewrite target',      rewriteTarget,      'for URL',      req.url     );    }    logger('Rewriting', req.method, req.url, 'to', rewriteTarget);    // 進行重定向url操作    req.url = rewriteTarget;    return next();   }  }  var pathname = parsedUrl.pathname;  // 首先說明一下:校驗邏輯默認是會去檢查url中最后的.號的,有.號的說明在請求文件,那就跟history模式就沒什么鳥關系了  // 我暫且將上述規則成為“點號校驗規則”  // disableDotRule為true,代表禁用點號校驗規則  if (pathname.lastIndexOf('.') > pathname.lastIndexOf('/') &&    options.disableDotRule !== true) {   // 如果pathname的最后一個/之后還有.,說明請求的是/a/b/c/d.*的文件(*代表任意文件類型);   // 如果此時配置disableDotRule為false,說明開啟點號校驗規則,那么不予處理,交給其他中間件   logger(    'Not rewriting',    req.method,    req.url,    'because the path includes a dot (.) character.'   );   return next();  }  // 如果pathname最后一個/之后沒有.,或者disableDotRule為true,都會走到最后一步:重寫url  // 重寫url有默認值/index.html,也可以通過配置中的index自定義  rewriteTarget = options.index || '/index.html';  logger('Rewriting', req.method, req.url, 'to', rewriteTarget);  // 重寫url  req.url = rewriteTarget;  // 此時再將執行權交給下一個中間件(url都換成index.html了,后面的路由等中間件也不會再處理了,然后前端接收到html就開始解析路由了,目的達到?。? next(); };};// 判斷重定向配置中的tofunction evaluateRewriteRule(parsedUrl, match, rule, req) { if (typeof rule === 'string') {  // 如果是字符串,直接返回  return rule; } else if (typeof rule !== 'function') {  // 如果不是函數,拋出錯誤  throw new Error('Rewrite rule can only be of type string or function.'); } // 執行自定義的回調函數,得到一個重定向的url return rule({  parsedUrl: parsedUrl,  match: match,  request: req });}// 判斷請求頭的accept是不是包含在配置數組或默認數組的范圍內function acceptsHtml(header, options) { options.htmlAcceptHeaders = options.htmlAcceptHeaders || ['text/html', '*/*']; for (var i = 0; i < options.htmlAcceptHeaders.length; i++) {  if (header.indexOf(options.htmlAcceptHeaders[i]) !== -1) {   return true;  } } return false;}// 處理日志function getLogger(options) { if (options && options.logger) {  // 如果有指定的日志方法,則使用指定的日志方法  return options.logger; } else if (options && options.verbose) {  // 否則,如果配置了verbose,默認使用console.log作為日志方法  return console.log.bind(console); } // 否則就沒有日志方法,就不記錄日志咯 return function(){};}

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VeVb武林網。


注:相關教程知識閱讀請移步到JavaScript/Ajax教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
久久久久女教师免费一区| 一区二区欧美激情| 欧美xxxx14xxxxx性爽| 日韩av最新在线观看| 久久久久久av| 欧美日韩国产精品一区二区不卡中文| 久久99热精品这里久久精品| 日本国产精品视频| 亚洲综合社区网| 久久久久一本一区二区青青蜜月| 亚洲国产精品资源| 久久亚洲春色中文字幕| 中文一区二区视频| 韩日精品中文字幕| 亚洲精品自拍偷拍| 成人精品网站在线观看| 成人免费在线视频网站| 尤物九九久久国产精品的分类| 97视频免费看| 欧美高清第一页| 欧美大尺度在线观看| 亚洲人成电影网站色www| 国内精品久久久久影院优| 国产精品久久久久久久久久三级| 国产丝袜高跟一区| 国产精品私拍pans大尺度在线| 色老头一区二区三区在线观看| 精品日本高清在线播放| 日韩大胆人体377p| 日韩av在线一区二区| 26uuu亚洲国产精品| 国产99久久精品一区二区永久免费| 久久人91精品久久久久久不卡| 国产精品偷伦免费视频观看的| 国产91色在线播放| 国产成人av网址| 中国china体内裑精亚洲片| 91亚洲精品一区| 91sao在线观看国产| 亚洲free性xxxx护士hd| 亚洲天堂av在线免费| 亚洲精品福利免费在线观看| 亚洲国产精品女人久久久| 精品一区精品二区| 日韩欧美在线国产| 伦伦影院午夜日韩欧美限制| 亚洲xxxx做受欧美| 久久99亚洲热视| 久久久久www| 亚洲免费成人av电影| 亚洲欧美日韩一区二区三区在线| 97在线视频精品| 青青久久aⅴ北条麻妃| 亚洲一区二区三区香蕉| 中文字幕免费精品一区| 俺去啦;欧美日韩| 欧美视频中文字幕在线| 国产精品第100页| 久久成年人免费电影| 精品激情国产视频| 精品无码久久久久久国产| 日韩中文在线中文网三级| 亚洲理论片在线观看| 91av免费观看91av精品在线| 精品欧美激情精品一区| 日韩在线观看视频免费| 成人美女av在线直播| 丰满岳妇乱一区二区三区| 成人av资源在线播放| 精品国内自产拍在线观看| 狠狠躁天天躁日日躁欧美| 国内外成人免费激情在线视频网站| 57pao精品| yellow中文字幕久久| 久久久亚洲欧洲日产国码aⅴ| 欧美日韩一区二区精品| 成人性生交xxxxx网站| 日韩成人在线视频观看| 国产精品入口免费视| 第一福利永久视频精品| 精品调教chinesegay| 欧美激情一区二区三区成人| 91精品久久久久久久久久入口| 色妞欧美日韩在线| 亚洲第一偷拍网| 九九九热精品免费视频观看网站| 亚洲美女自拍视频| 日本国产高清不卡| 欧美日韩国产精品一区| 国内精品久久久久久| 亚洲综合中文字幕在线观看| 国产精品久久91| 国产一区二中文字幕在线看| 日韩av在线网页| 亚洲三级黄色在线观看| 国产精品大陆在线观看| 国产日韩欧美夫妻视频在线观看| 日韩欧美中文字幕在线播放| 国产欧美日韩免费看aⅴ视频| 欧美韩国理论所午夜片917电影| 在线观看日韩专区| 欧美性高跟鞋xxxxhd| 中文.日本.精品| 96pao国产成视频永久免费| 亚洲va国产va天堂va久久| 日本sm极度另类视频| 日本一区二三区好的精华液| 国产剧情久久久久久| 亚洲第一区在线| 日韩精品在线第一页| 日韩在线观看网址| 日韩国产在线播放| 欧美高清不卡在线| 青青久久av北条麻妃海外网| 欧美丝袜一区二区| 国产精品免费在线免费| 91精品国产自产在线观看永久| 91欧美精品午夜性色福利在线| 欧美中文字幕在线视频| 国产99在线|中文| 国产日韩av在线播放| 久久躁狠狠躁夜夜爽| 亚洲免费视频网站| 亚洲欧洲国产一区| 在线亚洲男人天堂| 91国产精品视频在线| 亚洲国产精品大全| 91av在线不卡| y97精品国产97久久久久久| 中文字幕亚洲一区二区三区| 色婷婷**av毛片一区| 在线a欧美视频| 国产精品久久久久高潮| 精品久久久久久久大神国产| 欧美大片va欧美在线播放| 奇米4444一区二区三区| 清纯唯美亚洲激情| 国产精品电影在线观看| 欧美黄色性视频| 一区二区欧美久久| 日韩中文字幕网站| 97视频在线观看视频免费视频| 神马久久桃色视频| 久久躁日日躁aaaaxxxx| 欧美日韩美女视频| 97国产在线观看| 亚洲欧美日韩国产中文专区| 日韩大陆欧美高清视频区| 久久久久久这里只有精品| 日韩在线高清视频| 色中色综合影院手机版在线观看| 久久成人亚洲精品| 黑人极品videos精品欧美裸| 欧美噜噜久久久xxx| 亚洲欧美国产高清va在线播| 中文综合在线观看| 91精品国产高清| 日韩精品在线看| 国产精品色婷婷视频| 久久久久久久久久久久久久久久久久av| 国产日韩中文字幕| 欧美黑人xxxx| 国产做受高潮69| 亚洲国产精品va在线|