【问题标题】:D3.json Unexpected token with Node.js ServerD3.json Node.js 服务器的意外令牌
【发布时间】:2019-06-20 17:14:33
【问题描述】:

试图学习 D3 我写了以下本地服务器:

const http = require('http');
const fs = require('fs'); 

function onRequest(request, response) {
    response.writeHead(200, {'Content-Type': 'text/html'});
    fs.readFile('./index.html', null, function(error, data) {
        if (error) {
            response.writeHead(404);
            // response.write('file not found');
        } else {
            response.write(data);
        }
        response.end();
    });

}

http.createServer(onRequest).listen(8000, '127.0.0.1');

然后我去http://127.0.0.1:8000/渲染这个index.html:

<html>
<body>
<script src="https://d3js.org/d3.v5.min.js"></script>
<script>

    var stringit = `[{"coin_val": 4999999,"coin_lab": "#PAX"},{"coin_val": 1100000,"coin_lab": "#USDC"}]`;

    console.log('working.')

    d3.json('./data.json', function(err, data) {
        console.log(err)
        console.log(data)
    });
</script>

</body>
</html>

但我在 Chrome 控制台中收到以下错误:

Uncaught (in promise) SyntaxError: Unexpected token

我做错了什么?是我的 3D 代码还是我没有得到正确的服务器?如何让 D3 读取 Node.js 服务器中的 JSON 文件?

我怀疑 JSON 不是问题,服务器端出现问题并以错误的方式读取 HTML?

【问题讨论】:

  • d3.json 需要正确的 json 语法,而不是 JavaScript 对象。 learnjsdata.com/read_data.html。它不起作用,因为您将 json 解析为 JavaScript 对象。
  • 即使给 d3.json(./data.json) 它也会给我同样的问题
  • 你试过 console.log(data[0]) 我认为这是你的问题,因为它是一个数组。
  • 让我知道它是否有效,我可以将其作为答案提交:)
  • 数据[0]不走运,数据是'未定义'

标签: javascript node.js d3.js localserver


【解决方案1】:

我写了以下本地服务器

它提供index.html 的内容以响应它收到的任何请求。

d3.json('./data.json',

所以你的 JavaScript 请求 data.json 并获得 index.html 的内容。

由于index.html 的内容不是JSON,并且以&lt; 开头,因此会抛出错误消息。 JSON 文件不能以 &lt; 开头。

您需要修复您的服务器,以便它为浏览器提供所需的内容,而不是盲目地发送index.html

【讨论】:

  • 好吧,这对我来说相当困难,因为我实际上并不了解 node.js 服务器。对于服务 D3 的 Node.js,我也找不到任何指南。我想初学者使用node.js运行D3不是一个好主意,也许我应该坚持使用python。
  • 也许只是安装 Apache HTTP、Lighttpd、Nginx 或其他一些常见的 HTTP 服务器,而不是自己编写。
  • 是的,这就是我一直在寻找的答案,我猜 >python3 -m http.server
【解决方案2】:

您的问题似乎是您的代码不知道如何提供除 index.html 之外的任何内容。使用纯节点服务器真的很令人沮丧,因为互联网上的大多数资源都假设用户将使用 express 或其他框架。

下面我有一个服务器,它可以为静态网站提供服务并处理一些常见媒体类型的请求。您可以通过查找该文件格式的 mime 类型来修改 getContentType 函数中的代码来添加其他类型。

希望对你有帮助

'use strict'


// Step 1: Declare Constants and Require External Resources

const port  = "8888", landing = 'index.html', hostname = "127.0.0.1";
const path  = require('path');
const http  = require('http');
const fs    = require('fs');
const qs    = require('querystring');


// Step 2: Create getContentType Function that Returns the Requested MimeType for the browser

/**
 * getContentType :: str -> str
 * 
 * Function returns the content type that matches the resource being
 *  requested by the server controller 
 */
function getContentType(url){

    const mimeTypes = {
        '.html' : 'text/html'               ,   '.js'   : 'text/javascript'                 ,
        '.css'  : 'text/css'                ,   '.json' : 'application/json'                ,
        '.png'  : 'image/png'               ,   '.jpg'  : 'image/jpg'                       ,
        '.gif'  : 'image/gif'               ,   '.svg'  : 'image/svg+xml'                   ,
        '.wav'  : 'audio/wav'               ,   '.mp4'  : 'video/mp4'                       ,
        '.woff' : 'application/font-woff'   ,   '.ttf'  : 'application/font-ttf'            ,
        '.otf'  : 'application/font-otf'    ,   '.eot'  : 'application/vnd.ms-fontobject'   ,
        '.wasm' : 'application/wasm'        
    };

    // If requested url extension is a mime type, the dict object will return that url's value, 
    //      otherwise octet-stream will be returned instead
    return mimeTypes[path.extname(url).toLowerCase()] || 'application/octet-stream';
}


// Step 3: Create sendFile Function that Delivers Requested files to the Response stream

/**
 * sendFile :: (str, str, str, stream) -> void
 * 
 * function delivers any requested resources to the stream
 */
function sendFile(file, url, contentType, request, response){
    fs.readFile(file, (error, content) => {
        if(error) {
            response.writeHead(404)
                    .write(`404 Error: '${url}' Was Not Found!`);

            response.end();
            // include file path for easy debugging, tabs added to make distinct
            console.log(`\t${request.method} Response: 404 Error, '${file}' Was Not Found!`);
        } else {
            response.writeHead(200, {'Content-Type': contentType})
                    .write(content);

            response.end();
            console.log(`\t${request.method} Response: 200, ${url} Served`);
        };
    });
};



// Step 4: Create serverController Function to initialize the server and run the request loop

/**
 * serverController :: str -> void
 * 
 * Function creates a server and accesses sendFile and getContentType to serve 
 *  requested resources 
 */
function serverController(hostname) {
    const server = http.createServer((request, response) => {

        // Creates space around .html requests so that they stand out more in the console
        if (path.extname(request.url) == '.html' || request.url == '/') {
            console.log(`\nPage Requested: ${request.url}\n`);
        } else {
            if (request.method == "GET") {
                console.log(`${request.method} Request: ${request.url}`);
            } else {
                console.log(`Request came: ${request.url}`);
            }
        }

        // Sends the requested resources to the response stream
        if (request.url == '/') {
            var file = path.join(__dirname, landing);       // delivers index.html by default
            sendFile(file, landing, 'text/html', request, response);
        } else {
            var file = path.join(__dirname, request.url);   // delivers requested resource
            sendFile(file, request.url, getContentType(request.url), request, response);
        };
    });

    // Gives server a port to listen to and gives an IP address to find it
    server.listen(port, hostname, () => {
        console.log(`Server running at ${hostname}:${port}\n`);
    });
}


// Step 6: Create launch IIFE Function that Starts the server upon Instantiation

(function launch() {
    serverController(hostname);
})();

【讨论】:

    猜你喜欢
    • 2012-09-21
    • 1970-01-01
    • 1970-01-01
    • 2016-08-19
    • 2020-01-20
    • 2016-08-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多