首页 > 解决方案 > NodeJS 服务器中的 Mimetype 不匹配

问题描述

我在尝试使用 NodeJS 提供名为 index.html 的 HTML 文件时收到 mime 类型不匹配消息。警告如下:

The stylesheet http://localhost:8081/styling.css was not loaded because its MIME type, "text/html", is not "text/css".

The script from “http://localhost:8081/script.js” was loaded even though its MIME type (“text/html”) is not a valid JavaScript MIME type.

错误截图:

在此处输入图像描述

文件列表截图:

在此处输入图像描述


NodeJS 服务器代码:

#!/usr/bin/env node

const FS = require('fs')
const HTTP = require('http')
const Server = HTTP.createServer( response )
const Path = require('path')

let PORT = 8080

listen = () => {
    Server.listen(PORT, 'localhost').on('error', e => {
        console.log(`Trying to listen to port ${++PORT}`)
        listen()
    })
}

function response(r, c) {
    let d = new Date()
    console.log(`Respond Fired at ${d.getHours()}:${d.getMinutes()}:${d.getSeconds()}`)

    c.setHeader('Content-Type', 'text/plain')
    c.writeHead(200, { 'Content-Type': 'text/html' } )

    c.write(FS.readFileSync(Path.join(__dirname, 'index.html')))
    c.end()
}

listen()


index.html 的内容:

<!Doctype HTML>

<html>
    <head>
        <meta charset="utf-8">
        <link rel="stylesheet" href="styling.css">
    </head>

    <body>
        <p>Hello World!</p>
        <script type="application/javascript" src="script.js"></script>
    </body>
</html>

style.css 的内容:

p {
    color: #f55 ;
}

script.js 的内容:

document.write('Hello World from JavaScript!')

浏览器:

火狐 73.0b9(64 位)

标签: javascriptnode.js

解决方案


问题在于设置正确的 mimetypes。该问题可以通过读取请求文件的扩展名来设置 mime 类型来解决。

答案可以在这里找到: https ://stackoverflow.com/a/29046869/11089758

例如:

#!/usr/bin/env node

const FS = require('fs')
const HTTP = require('http')
const Server = HTTP.createServer( response )
const Path = require('path')
const URL = require('url')

let PORT = 8080

const ContentTypes = {
    '.ico': 'image/x-icon',
    '.html': 'text/html',
    '.js': 'application/javascript',
    '.json': 'text/json',
    '.css': 'text/css',
    '.png': 'image/png',
    '.jpg': 'image/jpeg',
    '.wav': 'audio/wav',
    '.mp3': 'audio/mp3',
    '.svg': 'image/svg+xml',
    '.pdf': 'application/pdf',
    '.doc': 'application/doc'
}

listen = () => {
    Server.listen(PORT, 'localhost').on('error', e => {
        console.log(`Trying to listen to port ${++PORT}`)
        listen()
    })
}

function response(r, c) {
    let d = new Date(), pathname = Path.join( __dirname, URL.parse(r.url).pathname )
    console.log(`Respond Fired at ${d.getHours()}:${d.getMinutes()}:${d.getSeconds()}`)

    try { var lstatSync = FS.lstatSync(pathname) } catch { return false }

    let readFile = lstatSync.isDirectory() ? Path.join(__dirname, 'index.html') : pathname
    let head = ContentTypes[Path.extname(readFile)] || 'text/plain', data = ''

    try { data = FS.readFileSync(readFile, 'utf-8') } catch(err) { console.log(err) }

    c.setHeader('Access-Control-Allow-Origin', '*')
    c.writeHead( 200, { 'Content-Type':  head } )
    c.end(data)
}

listen()

我们还需要检查当前路径是否是一个目录,在这种情况下,我们正在服务index.html并将头设置为'Content-Type': 'text/html',否则它会在对象(哈希表)中查找,如果没有找到扩展名,则将其设置为text/plain


推荐阅读