又来写点了,之前玩物丧志,然后跳槽,搬家,安顿,比较折腾了,没怎么学习和记笔记,哈哈哈哈
首先起一个简单的服务,新建一个 js
文件,写入以下命令,并用 node xx.js
运行起来,之后在浏览器中访问 本地3000 端口。
// 导入内置模块 http
const http = require("http");
// 创建服务
const server = http.createServer((req, res) => {
res.end("hello Node.js");
});
// 启动服务,监听 3000 端口
server.listen(3000);
如果我返回一些中文,之后页面会出现如下乱码
const http = require("http");
const server = http.createServer((req, res) => {
res.end("你好 Node.js");
});
server.listen(3000);
// 页面
浣犲ソ Node.js
这是因为我们没有设置返回的文字编码,解决的办法就是 添加页面文字编码
const http = require("http");
const server = http.createServer((req, res) => {
res.setHeader('content-type','text/html;charset=utf-8') // 添加页面文字编码
res.end("你好 Node.js");
});
server.listen(3000);
可以通过 req.url
判断用户访问的那个地址,req.url
是用户在地址栏中输入的端口号后面的字符串,栗子:http://localhost:3000/index 或者是 http://localhost:3000/song。
req.url
也会带 ?
后面的参数,比方说 http://localhost:3000/song?name=周杰伦
这个时候 req.url
就等于 /song?name=周杰伦
了。
const http = require("http");
const server = http.createServer((req, res) => {
let url = req.url;
res.setHeader("content-type", "text/html;charset=utf-8");
if (url === "/" || url === "/index") {
res.end("主页");
} else {
res.end("其他页面");
}
});
server.listen(3000);
那这样的话就会出现问题,路由会匹配不到的,这时候我们就要想如何拿到不带参数的路由名称。
这里有个新的内置模块 url
他会帮你解析一下
const http = require("http");
const url = require("url");
const server = http.createServer((req, res) => {
res.setHeader("content-type", "text/html;charset=utf-8");
let reqUrl = req.url;
let realUrl = url.parse(reqUrl); // 解析 url,可以打印一下 realUrl 查看
console.log(realUrl);
if (realUrl.pathname === "/" || realUrl.pathname === "/index") {
res.end("主页");
} else {
res.end("其他页面");
}
});
server.listen(3000);
当我们想要给前端返回一个页面的时候,我们需要先加载一下 html
文件,然后返回
这里在插一嘴:前端的所有路由都是假路由!
首先呢,在项目下新建一个 view
文件夹,里面存放着我么要返回给前端展示的页面html
文件
然后写好html
,运行下面的 node
脚本
const http = require("http");
const url = require("url");
const fs = require('fs')
const server = http.createServer((req, res) => {
res.setHeader("content-type", "text/html;charset=utf-8");
let reqUrl = req.url;
let realUrl = url.parse(reqUrl);
console.log(realUrl);
if (realUrl.pathname === "/" || realUrl.pathname === "/index") {
let htmlData = fs.readFileSync('./view/index.html')
res.end(htmlData);
} else {
let htmlData = fs.readFileSync('./view/other.html')
res.end(htmlData);
}
});
server.listen(3000);
当然,如果html
文件比较大的话,一次性读到内存,对于比较次的电脑会比较吃力,我们可以通过流读取来优化一下。
const http = require("http");
const url = require("url");
const fs = require("fs");
const server = http.createServer((req, res) => {
res.setHeader("content-type", "text/html;charset=utf-8");
let reqUrl = req.url;
let realUrl = url.parse(reqUrl);
if (realUrl.pathname === "/" || realUrl.pathname === "/index") {
// 流方式:节约内存
let rs = fs.createReadStream("./view/index.html");
// 通过管道写到 res 里
rs.pipe(res);
} else {
let rs = fs.createReadStream("./view/other.html");
rs.pipe(res);
}
});
server.listen(3000);
当我们在 index.html
页面上引入了一个脚本的时候
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
<script src="./a.js">script>
head>
<body>
<h2>我是主页h2>
body>
html>
此时,这个 a.js 会有作用吗?
访问一下http://localhost:3000/ 后,发现报错了
Uncaught SyntaxError: Unexpected token ‘<’
这是我们引入的资源不正确导致的,至于为什么报这个错误,我也不懂~
我是知道 a.js
这个文件页面它没找到,那如何处理呢?我们也需要把这个 js
读出取来,然后放到res
里
为什么这么可以呢?浅显的理解就是:当页面发现你引入了 a.js
的时候,会发起一个请求,去后台请求 a.js
,这个是在 createServer
里能打印出来的。
const http = require("http");
const url = require("url");
const fs = require("fs");
const server = http.createServer((req, res) => {
res.setHeader("content-type", "text/html;charset=utf-8");
let reqUrl = req.url;
let realUrl = url.parse(reqUrl);
console.log(reqUrl);
if (realUrl.pathname === "/" || realUrl.pathname === "/index") {
let rs = fs.createReadStream("./view/index.html");
rs.pipe(res);
} else if(realUrl.pathname === '/other'){
let rs = fs.createReadStream("./view/other.html");
rs.pipe(res);
} else {
// 处理 a.js
// 你会发现,在html 中引入的资源也会在 req.url 中找到
let rs = fs.createReadStream('./view' + realUrl.pathname)
rs.pipe(res)
}
});
server.listen(3000);
此时 a.js
就可以正常的引入了,不过会报错,因为找不到 favicon.ico
,这个先不用管,或者添加个if
条件,也并不是重点,只需要了解知道即可。
我们请求的所有资源都会走
createServer
的,比方说页面中引入了a.js
,那么他也会走一遍createServer
比较隐形的例子就是favicon.ico
了!所以你会疑惑,为什么上面的代码req
打印了两遍,原因可能是这个哦。
此时还会有一个问题,所有的资源需要配置适合自己的 Content-type
,否则就会出现错误或者失效,比方说我写一个 css
,并在页面中引入
// css 文件
body{
background: red;
}
// index.js
// 服务器启动脚本
const http = require("http")
const url = require("url")
const fs = require("fs")
// const mime = require("./mime.json") // 注意这里注释掉了~等会记得松开注释
const path = require("path")
const server = http.createServer((req, res) => {
res.setHeader("content-type", "text/html;charset=utf-8")
let urlObj = url.parse(req.url)
console.log(urlObj.pathname)
if (urlObj.pathname === "/" || urlObj.pathname === "/index") {
let indexData = fs.createReadStream("./views/index.html")
indexData.pipe(res)
} else {
if (urlObj.pathname !== "/favicon.ico") {
// let ext = path.extname(urlObj.pathname)
// res.setHeader("Content-Type", mime[ext]) // 通过请求的资源后缀名,来返回对应的 Content-type 的类型
let resData = fs.createReadStream("./views" + urlObj.pathname)
resData.pipe(res)
}
}
})
server.listen(3001);
页面样式如下
而且页面的效果也没有,这个css根本没起作用啊,所以要配置一下
const http = require("http")
const url = require("url")
const fs = require("fs")
const mime = require("./mime.json") // 引入 MIME
const path = require("path")
const server = http.createServer((req, res) => {
res.setHeader("content-type", "text/html;charset=utf-8")
let urlObj = url.parse(req.url)
console.log(urlObj.pathname)
if (urlObj.pathname === "/" || urlObj.pathname === "/index") {
let indexData = fs.createReadStream("./views/index.html")
indexData.pipe(res)
} else {
if (urlObj.pathname !== "/favicon.ico") {
let ext = path.extname(urlObj.pathname)
res.setHeader("Content-Type", mime[ext]) // 通过请求的资源后缀名,来返回对应的 Content-type 的类型
let resData = fs.createReadStream("./views" + urlObj.pathname)
resData.pipe(res)
}
}
})
server.listen(3001);
其中 MIME.json
的代码在文章的最下面。
我单独提取出来了,放在一篇文章里太挤了。
官网戳我,它是 express
原班人马制作的,比 express
更加轻量。
可以和原生 node
做个对比
// Node 原生
const http = require("http");
const server = http.createServer((req, res) => {
res.end("hello Node.js");
});
server.listen(3000);
// Koa
const Koa = require("koa");
const app = new Koa();
app.use((ctx, next) => {
ctx.body = "你好";
});
app.listen(3000);
感觉好像也没简单多少啊,别急,看看它是如何处理路由还有其他的功能的。
koa
中引入了中间件这个东西,中间件会把回调函数里面写的功能,添加到 app
实例中去,比方说上面的
app.use((ctx, next) => {
ctx.body = "你好";
});
其中 ctx
是 context
的缩写,意为上下文,可以让上下中间件产生关联。
原生 node
中的 res
被 koa 封装到了 ctx.res
里,req
也是同理的,这个知识点在 Koa
官网中称之为 别名
比方说别人已经封装好了几个功能(中间件),我们引入后,拿来 app.use()
即可。
const Koa = require("koa");
const app = new Koa();
let middleware1 = async function (ctx, next) {
console.log("假设我是一个封装好的中间件1");
await next();
};
let middleware2 = async function (ctx, next) {
console.log("假设我是一个封装好的中间件2");
await next();
};
app.use(middleware1);
app.use(middleware2);
app.listen(3000);
其中 next
是转交的功能。会把函数放到异步队列中
遵循洋葱模型
,可以理解成把 next()
替换成 下一个中间件的函数语句。
const Koa = require("koa");
const app = new Koa();
let middleware1 = async function (ctx, next) {
console.log("one start...");
ctx.body = "hello";
await new Promise((resolve) => {
setTimeout(() => {
console.log('异步操作');
resolve()
}, 1000);
})
await next();
console.log("one end...")
};
let middleware2 = async function (ctx, next) {
console.log("two start...")
ctx.body = "world";
console.log("two end...")
};
app.use(middleware1);
app.use(middleware2);
app.listen(3000);
如果那个中间件出现了错误,可以通过监听 error
事件,来打印 & 处理异常。
app.on('error', err => {
console.log(err);
})
路由需要我们引入路由组件 require("koa-router")
const Koa = require("koa");
const Router = require("koa-router");
let app = new Koa();
let router = new Router();
router.get("/", async (ctx, next) => {
// 加载页面
await ctx.render("index.pug");
});
app.use(router.routes());
app.listen(3000);
router.get
就相当于 用 get
方式请求后台,其他请求方式类似。
有了中间件,可以省了不少的事情,可以跟原生的做个对比~
const Koa = require("koa");
const Router = require("koa-router");
const views = require("koa-views");
let app = new Koa();
let router = new Router();
// 使用中间件,告诉我们的页面文件的路径在哪儿
// 其中第二个参数:配置模板引擎的格式
app.use(views(__dirname + "/views"), {
extension: "pug"
});
router.get("/", async (ctx, next) => {
// 加载页面
await ctx.render("index.pug");
});
app.use(router.routes());
app.listen(3000);
这个组件叫做:静态 web 托管服务中间件
这也是一个外部的中间件,需要 npm install koa-static
,你会发现比原生的 fs 模块要简单很多。
基本的思路就是:
Node.js
的API
返回对应的文件,并设置相应的header
实例:我们先在 index.pug
中引入一个脚本
doctype html
html(lang='en')
head
meta(charset='UTF-8')
meta(name='viewport', content='width=device-width, initial-scale=1.0')
meta(http-equiv='X-UA-Compatible', content='ie=edge')
script(src="a.js")
title Document
body
h1
| 测试标题pug
然后执行 一下脚本,启动服务
const Koa = require("koa");
const Router = require("koa-router");
const views = require("koa-views");
const static = require ("koa-static")
let app = new Koa();
let router = new Router();
app.use(views(__dirname + "/views"), {
extension: "pug"
});
app.use(static(__dirname + '/static')); // 添加查找静态资源的中间件,配置路径
router.get("/", async (ctx, next) => {
await ctx.render("index.pug");
});
app.use(router.routes());
app.listen(3000);
发现可以正常加载脚本!!ok
在 Node 原生的讲解可以知道,引入外部资源也是一种请求,浏览器会发起一个请求到后台,我们后台需要找到文件并返回给浏览器~
我们用推荐的写法之所以能找到,是因为后端找到了这个资源
如果你用./static/a.js
这样引入的话,你以为页面能够正确引入,实则非也。
原因是因为,如果你是这样声明的话,Node 就会去访问 /static
下的文件,并把它替代成 localhost:3000
// 这里声明成这样子,后端会在遇到请求静态资源的时候,到 dirname + '/static' 这个路径下去寻找
// 前端请求的样子是:localhost:3000/a.js
app.use(static(__dirname + '/static'));
如需想要获取 post
请求来的参数的话,需要添加这个中间件
不然拿不到 post
发过来的参数,打印出来的也是 undefined
const Body = require('koa-body')
app.use(
Body({
multipart: true,
})
)
// 取值
console.log(ctx.request.body)
取值可以通过 ctx.request.body
来拿到值。
有些请求默认是 get
的,比方说地址栏、脚本 scrip
的 src=""
、 img
图片的 src
、 href=""
这个 __dirname
是 Node
中的系统变量,它的值是当前所在文件的上一级文件夹的路径。
{ ".323":"text/h323" ,
".3gp":"video/3gpp" ,
".aab":"application/x-authoware-bin" ,
".aam":"application/x-authoware-map" ,
".aas":"application/x-authoware-seg" ,
".acx":"application/internet-property-stream" ,
".ai":"application/postscript" ,
".aif":"audio/x-aiff" ,
".aifc":"audio/x-aiff" ,
".aiff":"audio/x-aiff" ,
".als":"audio/X-Alpha5" ,
".amc":"application/x-mpeg" ,
".ani":"application/octet-stream" ,
".apk":"application/vnd.android.package-archive" ,
".asc":"text/plain" ,
".asd":"application/astound" ,
".asf":"video/x-ms-asf" ,
".asn":"application/astound" ,
".asp":"application/x-asap" ,
".asr":"video/x-ms-asf" ,
".asx":"video/x-ms-asf" ,
".au":"audio/basic" ,
".avb":"application/octet-stream" ,
".avi":"video/x-msvideo" ,
".awb":"audio/amr-wb" ,
".axs":"application/olescript" ,
".bas":"text/plain" ,
".bcpio":"application/x-bcpio" ,
".bin ":"application/octet-stream" ,
".bld":"application/bld" ,
".bld2":"application/bld2" ,
".bmp":"image/bmp" ,
".bpk":"application/octet-stream" ,
".bz2":"application/x-bzip2" ,
".c":"text/plain" ,
".cal":"image/x-cals" ,
".cat":"application/vnd.ms-pkiseccat" ,
".ccn":"application/x-cnc" ,
".cco":"application/x-cocoa" ,
".cdf":"application/x-cdf" ,
".cer":"application/x-x509-ca-cert" ,
".cgi":"magnus-internal/cgi" ,
".chat":"application/x-chat" ,
".class":"application/octet-stream" ,
".clp":"application/x-msclip" ,
".cmx":"image/x-cmx" ,
".co":"application/x-cult3d-object" ,
".cod":"image/cis-cod" ,
".conf":"text/plain" ,
".cpio":"application/x-cpio" ,
".cpp":"text/plain" ,
".cpt":"application/mac-compactpro" ,
".crd":"application/x-mscardfile" ,
".crl":"application/pkix-crl" ,
".crt":"application/x-x509-ca-cert" ,
".csh":"application/x-csh" ,
".csm":"chemical/x-csml" ,
".csml":"chemical/x-csml" ,
".css":"text/css" ,
".cur":"application/octet-stream" ,
".dcm":"x-lml/x-evm" ,
".dcr":"application/x-director" ,
".dcx":"image/x-dcx" ,
".der":"application/x-x509-ca-cert" ,
".dhtml":"text/html" ,
".dir":"application/x-director" ,
".dll":"application/x-msdownload" ,
".dmg":"application/octet-stream" ,
".dms":"application/octet-stream" ,
".doc":"application/msword" ,
".docx":"application/vnd.openxmlformats-officedocument.wordprocessingml.document" ,
".dot":"application/msword" ,
".dvi":"application/x-dvi" ,
".dwf":"drawing/x-dwf" ,
".dwg":"application/x-autocad" ,
".dxf":"application/x-autocad" ,
".dxr":"application/x-director" ,
".ebk":"application/x-expandedbook" ,
".emb":"chemical/x-embl-dl-nucleotide" ,
".embl":"chemical/x-embl-dl-nucleotide" ,
".eps":"application/postscript" ,
".epub":"application/epub+zip" ,
".eri":"image/x-eri" ,
".es":"audio/echospeech" ,
".esl":"audio/echospeech" ,
".etc":"application/x-earthtime" ,
".etx":"text/x-setext" ,
".evm":"x-lml/x-evm" ,
".evy":"application/envoy" ,
".exe":"application/octet-stream" ,
".fh4":"image/x-freehand" ,
".fh5":"image/x-freehand" ,
".fhc":"image/x-freehand" ,
".fif":"application/fractals" ,
".flr":"x-world/x-vrml" ,
".flv":"flv-application/octet-stream" ,
".fm":"application/x-maker" ,
".fpx":"image/x-fpx" ,
".fvi":"video/isivideo" ,
".gau":"chemical/x-gaussian-input" ,
".gca":"application/x-gca-compressed" ,
".gdb":"x-lml/x-gdb" ,
".gif":"image/gif" ,
".gps":"application/x-gps" ,
".gtar":"application/x-gtar" ,
".gz":"application/x-gzip" ,
".h":"text/plain" ,
".hdf":"application/x-hdf" ,
".hdm":"text/x-hdml" ,
".hdml":"text/x-hdml" ,
".hlp":"application/winhlp" ,
".hqx":"application/mac-binhex40" ,
".hta":"application/hta" ,
".htc":"text/x-component" ,
".htm":"text/html" ,
".html":"text/html" ,
".hts":"text/html" ,
".htt":"text/webviewhtml" ,
".ice":"x-conference/x-cooltalk" ,
".ico":"image/x-icon" ,
".ief":"image/ief" ,
".ifm":"image/gif" ,
".ifs":"image/ifs" ,
".iii":"application/x-iphone" ,
".imy":"audio/melody" ,
".ins":"application/x-internet-signup" ,
".ips":"application/x-ipscript" ,
".ipx":"application/x-ipix" ,
".isp":"application/x-internet-signup" ,
".it":"audio/x-mod" ,
".itz":"audio/x-mod" ,
".ivr":"i-world/i-vrml" ,
".j2k":"image/j2k" ,
".jad":"text/vnd.sun.j2me.app-descriptor" ,
".jam":"application/x-jam" ,
".jar":"application/java-archive" ,
".java":"text/plain" ,
".jfif":"image/pipeg" ,
".jnlp":"application/x-java-jnlp-file" ,
".jpe":"image/jpeg" ,
".jpeg":"image/jpeg" ,
".jpg":"image/jpeg" ,
".jpz":"image/jpeg" ,
".js":"application/x-javascript" ,
".jwc":"application/jwc" ,
".kjx":"application/x-kjx" ,
".lak":"x-lml/x-lak" ,
".latex":"application/x-latex" ,
".lcc":"application/fastman" ,
".lcl":"application/x-digitalloca" ,
".lcr":"application/x-digitalloca" ,
".lgh":"application/lgh" ,
".lha":"application/octet-stream" ,
".lml":"x-lml/x-lml" ,
".lmlpack":"x-lml/x-lmlpack" ,
".log":"text/plain" ,
".lsf":"video/x-la-asf" ,
".lsx":"video/x-la-asf" ,
".lzh":"application/octet-stream" ,
".m13":"application/x-msmediaview" ,
".m14":"application/x-msmediaview" ,
".m15":"audio/x-mod" ,
".m3u":"audio/x-mpegurl" ,
".m3url":"audio/x-mpegurl" ,
".m4a":"audio/mp4a-latm" ,
".m4b":"audio/mp4a-latm" ,
".m4p":"audio/mp4a-latm" ,
".m4u":"video/vnd.mpegurl" ,
".m4v":"video/x-m4v" ,
".ma1":"audio/ma1" ,
".ma2":"audio/ma2" ,
".ma3":"audio/ma3" ,
".ma5":"audio/ma5" ,
".man":"application/x-troff-man" ,
".map":"magnus-internal/imagemap" ,
".mbd":"application/mbedlet" ,
".mct":"application/x-mascot" ,
".mdb":"application/x-msaccess" ,
".mdz":"audio/x-mod" ,
".me":"application/x-troff-me" ,
".mel":"text/x-vmel" ,
".mht":"message/rfc822" ,
".mhtml":"message/rfc822" ,
".mi":"application/x-mif" ,
".mid":"audio/mid" ,
".midi":"audio/midi" ,
".mif":"application/x-mif" ,
".mil":"image/x-cals" ,
".mio":"audio/x-mio" ,
".mmf":"application/x-skt-lbs" ,
".mng":"video/x-mng" ,
".mny":"application/x-msmoney" ,
".moc":"application/x-mocha" ,
".mocha":"application/x-mocha" ,
".mod":"audio/x-mod" ,
".mof":"application/x-yumekara" ,
".mol":"chemical/x-mdl-molfile" ,
".mop":"chemical/x-mopac-input" ,
".mov":"video/quicktime" ,
".movie":"video/x-sgi-movie" ,
".mp2":"video/mpeg" ,
".mp3":"audio/mpeg" ,
".mp4":"video/mp4" ,
".mpa":"video/mpeg" ,
".mpc":"application/vnd.mpohun.certificate" ,
".mpe":"video/mpeg" ,
".mpeg":"video/mpeg" ,
".mpg":"video/mpeg" ,
".mpg4":"video/mp4" ,
".mpga":"audio/mpeg" ,
".mpn":"application/vnd.mophun.application" ,
".mpp":"application/vnd.ms-project" ,
".mps":"application/x-mapserver" ,
".mpv2":"video/mpeg" ,
".mrl":"text/x-mrml" ,
".mrm":"application/x-mrm" ,
".ms":"application/x-troff-ms" ,
".msg":"application/vnd.ms-outlook" ,
".mts":"application/metastream" ,
".mtx":"application/metastream" ,
".mtz":"application/metastream" ,
".mvb":"application/x-msmediaview" ,
".mzv":"application/metastream" ,
".nar":"application/zip" ,
".nbmp":"image/nbmp" ,
".nc":"application/x-netcdf" ,
".ndb":"x-lml/x-ndb" ,
".ndwn":"application/ndwn" ,
".nif":"application/x-nif" ,
".nmz":"application/x-scream" ,
".nokia-op-logo":"image/vnd.nok-oplogo-color" ,
".npx":"application/x-netfpx" ,
".nsnd":"audio/nsnd" ,
".nva":"application/x-neva1" ,
".nws":"message/rfc822" ,
".oda":"application/oda" ,
".ogg":"audio/ogg" ,
".oom":"application/x-AtlasMate-Plugin" ,
".p10":"application/pkcs10" ,
".p12":"application/x-pkcs12" ,
".p7b":"application/x-pkcs7-certificates" ,
".p7c":"application/x-pkcs7-mime" ,
".p7m":"application/x-pkcs7-mime" ,
".p7r":"application/x-pkcs7-certreqresp" ,
".p7s":"application/x-pkcs7-signature" ,
".pac":"audio/x-pac" ,
".pae":"audio/x-epac" ,
".pan":"application/x-pan" ,
".pbm":"image/x-portable-bitmap" ,
".pcx":"image/x-pcx" ,
".pda":"image/x-pda" ,
".pdb":"chemical/x-pdb" ,
".pdf":"application/pdf" ,
".pfr":"application/font-tdpfr" ,
".pfx":"application/x-pkcs12" ,
".pgm":"image/x-portable-graymap" ,
".pict":"image/x-pict" ,
".pko":"application/ynd.ms-pkipko" ,
".pm":"application/x-perl" ,
".pma":"application/x-perfmon" ,
".pmc":"application/x-perfmon" ,
".pmd":"application/x-pmd" ,
".pml":"application/x-perfmon" ,
".pmr":"application/x-perfmon" ,
".pmw":"application/x-perfmon" ,
".png":"image/png" ,
".pnm":"image/x-portable-anymap" ,
".pnz":"image/png" ,
".pot,":"application/vnd.ms-powerpoint" ,
".ppm":"image/x-portable-pixmap" ,
".pps":"application/vnd.ms-powerpoint" ,
".ppt":"application/vnd.ms-powerpoint" ,
".pptx":"application/vnd.openxmlformats-officedocument.presentationml.presentation" ,
".pqf":"application/x-cprplayer" ,
".pqi":"application/cprplayer" ,
".prc":"application/x-prc" ,
".prf":"application/pics-rules" ,
".prop":"text/plain" ,
".proxy":"application/x-ns-proxy-autoconfig" ,
".ps":"application/postscript" ,
".ptlk":"application/listenup" ,
".pub":"application/x-mspublisher" ,
".pvx":"video/x-pv-pvx" ,
".qcp":"audio/vnd.qcelp" ,
".qt":"video/quicktime" ,
".qti":"image/x-quicktime" ,
".qtif":"image/x-quicktime" ,
".r3t":"text/vnd.rn-realtext3d" ,
".ra":"audio/x-pn-realaudio" ,
".ram":"audio/x-pn-realaudio" ,
".rar":"application/octet-stream" ,
".ras":"image/x-cmu-raster" ,
".rc":"text/plain" ,
".rdf":"application/rdf+xml" ,
".rf":"image/vnd.rn-realflash" ,
".rgb":"image/x-rgb" ,
".rlf":"application/x-richlink" ,
".rm":"audio/x-pn-realaudio" ,
".rmf":"audio/x-rmf" ,
".rmi":"audio/mid" ,
".rmm":"audio/x-pn-realaudio" ,
".rmvb":"audio/x-pn-realaudio" ,
".rnx":"application/vnd.rn-realplayer" ,
".roff":"application/x-troff" ,
".rp":"image/vnd.rn-realpix" ,
".rpm":"audio/x-pn-realaudio-plugin" ,
".rt":"text/vnd.rn-realtext" ,
".rte":"x-lml/x-gps" ,
".rtf":"application/rtf" ,
".rtg":"application/metastream" ,
".rtx":"text/richtext" ,
".rv":"video/vnd.rn-realvideo" ,
".rwc":"application/x-rogerwilco" ,
".s3m":"audio/x-mod" ,
".s3z":"audio/x-mod" ,
".sca":"application/x-supercard" ,
".scd":"application/x-msschedule" ,
".sct":"text/scriptlet" ,
".sdf":"application/e-score" ,
".sea":"application/x-stuffit" ,
".setpay":"application/set-payment-initiation" ,
".setreg":"application/set-registration-initiation" ,
".sgm":"text/x-sgml" ,
".sgml":"text/x-sgml" ,
".sh":"application/x-sh" ,
".shar":"application/x-shar" ,
".shtml":"magnus-internal/parsed-html" ,
".shw":"application/presentations" ,
".si6":"image/si6" ,
".si7":"image/vnd.stiwap.sis" ,
".si9":"image/vnd.lgtwap.sis" ,
".sis":"application/vnd.symbian.install" ,
".sit":"application/x-stuffit" ,
".skd":"application/x-Koan" ,
".skm":"application/x-Koan" ,
".skp":"application/x-Koan" ,
".skt":"application/x-Koan" ,
".slc":"application/x-salsa" ,
".smd":"audio/x-smd" ,
".smi":"application/smil" ,
".smil":"application/smil" ,
".smp":"application/studiom" ,
".smz":"audio/x-smd" ,
".snd":"audio/basic" ,
".spc":"application/x-pkcs7-certificates" ,
".spl":"application/futuresplash" ,
".spr":"application/x-sprite" ,
".sprite":"application/x-sprite" ,
".sdp":"application/sdp" ,
".spt":"application/x-spt" ,
".src":"application/x-wais-source" ,
".sst":"application/vnd.ms-pkicertstore" ,
".stk":"application/hyperstudio" ,
".stl":"application/vnd.ms-pkistl" ,
".stm":"text/html" ,
".svg":"image/svg+xml" ,
".sv4cpio":"application/x-sv4cpio" ,
".sv4crc":"application/x-sv4crc" ,
".svf":"image/vnd" ,
".svg":"image/svg+xml" ,
".svh":"image/svh" ,
".svr":"x-world/x-svr" ,
".swf":"application/x-shockwave-flash" ,
".swfl":"application/x-shockwave-flash" ,
".t":"application/x-troff" ,
".tad":"application/octet-stream" ,
".talk":"text/x-speech" ,
".tar":"application/x-tar" ,
".taz":"application/x-tar" ,
".tbp":"application/x-timbuktu" ,
".tbt":"application/x-timbuktu" ,
".tcl":"application/x-tcl" ,
".tex":"application/x-tex" ,
".texi":"application/x-texinfo" ,
".texinfo":"application/x-texinfo" ,
".tgz":"application/x-compressed" ,
".thm":"application/vnd.eri.thm" ,
".tif":"image/tiff" ,
".tiff":"image/tiff" ,
".tki":"application/x-tkined" ,
".tkined":"application/x-tkined" ,
".toc":"application/toc" ,
".toy":"image/toy" ,
".tr":"application/x-troff" ,
".trk":"x-lml/x-gps" ,
".trm":"application/x-msterminal" ,
".tsi":"audio/tsplayer" ,
".tsp":"application/dsptype" ,
".tsv":"text/tab-separated-values" ,
".ttf":"application/octet-stream" ,
".ttz":"application/t-time" ,
".txt":"text/plain" ,
".uls":"text/iuls" ,
".ult":"audio/x-mod" ,
".ustar":"application/x-ustar" ,
".uu":"application/x-uuencode" ,
".uue":"application/x-uuencode" ,
".vcd":"application/x-cdlink" ,
".vcf":"text/x-vcard" ,
".vdo":"video/vdo" ,
".vib":"audio/vib" ,
".viv":"video/vivo" ,
".vivo":"video/vivo" ,
".vmd":"application/vocaltec-media-desc" ,
".vmf":"application/vocaltec-media-file" ,
".vmi":"application/x-dreamcast-vms-info" ,
".vms":"application/x-dreamcast-vms" ,
".vox":"audio/voxware" ,
".vqe":"audio/x-twinvq-plugin" ,
".vqf":"audio/x-twinvq" ,
".vql":"audio/x-twinvq" ,
".vre":"x-world/x-vream" ,
".vrml":"x-world/x-vrml" ,
".vrt":"x-world/x-vrt" ,
".vrw":"x-world/x-vream" ,
".vts":"workbook/formulaone" ,
".wav":"audio/x-wav" ,
".wax":"audio/x-ms-wax" ,
".wbmp":"image/vnd.wap.wbmp" ,
".wcm":"application/vnd.ms-works" ,
".wdb":"application/vnd.ms-works" ,
".web":"application/vnd.xara" ,
".wi":"image/wavelet" ,
".wis":"application/x-InstallShield" ,
".wks":"application/vnd.ms-works" ,
".wm":"video/x-ms-wm" ,
".wma":"audio/x-ms-wma" ,
".wmd":"application/x-ms-wmd" ,
".wmf":"application/x-msmetafile" ,
".wml":"text/vnd.wap.wml" ,
".wmlc":"application/vnd.wap.wmlc" ,
".wmls":"text/vnd.wap.wmlscript" ,
".wmlsc":"application/vnd.wap.wmlscriptc" ,
".wmlscript":"text/vnd.wap.wmlscript" ,
".wmv":"audio/x-ms-wmv" ,
".wmx":"video/x-ms-wmx" ,
".wmz":"application/x-ms-wmz" ,
".wpng":"image/x-up-wpng" ,
".wps":"application/vnd.ms-works" ,
".wpt":"x-lml/x-gps" ,
".wri":"application/x-mswrite" ,
".wrl":"x-world/x-vrml" ,
".wrz":"x-world/x-vrml" ,
".ws":"text/vnd.wap.wmlscript" ,
".wsc":"application/vnd.wap.wmlscriptc" ,
".wv":"video/wavelet" ,
".wvx":"video/x-ms-wvx" ,
".wxl":"application/x-wxl" ,
".x-gzip":"application/x-gzip" ,
".xaf":"x-world/x-vrml" ,
".xar":"application/vnd.xara" ,
".xbm":"image/x-xbitmap" ,
".xdm":"application/x-xdma" ,
".xdma":"application/x-xdma" ,
".xdw":"application/vnd.fujixerox.docuworks" ,
".xht":"application/xhtml+xml" ,
".xhtm":"application/xhtml+xml" ,
".xhtml":"application/xhtml+xml" ,
".xla":"application/vnd.ms-excel" ,
".xlc":"application/vnd.ms-excel" ,
".xll":"application/x-excel" ,
".xlm":"application/vnd.ms-excel" ,
".xls":"application/vnd.ms-excel" ,
".xlsx":"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" ,
".xlt":"application/vnd.ms-excel" ,
".xlw":"application/vnd.ms-excel" ,
".xm":"audio/x-mod" ,
".xml":"text/plain",
".xml":"application/xml",
".xmz":"audio/x-mod" ,
".xof":"x-world/x-vrml" ,
".xpi":"application/x-xpinstall" ,
".xpm":"image/x-xpixmap" ,
".xsit":"text/xml" ,
".xsl":"text/xml" ,
".xul":"text/xul" ,
".xwd":"image/x-xwindowdump" ,
".xyz":"chemical/x-pdb" ,
".yz1":"application/x-yz1" ,
".z":"application/x-compress" ,
".zac":"application/x-zaurus-zac" ,
".zip":"application/zip" ,
".json":"application/json"
}