D3.json Неожиданный токен с сервером Node.js

пытаясь изучить 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.info('working.')

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

</body>
</html>

но я получаю следующую ошибку в консоли Chrome:

Uncaught (in promise) SyntaxError: Unexpected token < in JSON at position 1 at Go (d3.v5.min.js:2) Go @ d3.v5.min.js:2

Что я делаю неправильно? это я 3D код или я просто не правильно понимаю сервер? как я могу заставить D3 читать файл JSON на сервере Node.js?

Я подозреваю, что проблема не в JSON, что-то идет не так на стороне сервера и неправильно читает HTML?

d3.json ожидает правильного синтаксиса json, а не объектов JavaScript. Learnjsdata.com/read_data.html. Это не работает, потому что вы анализируете json в объекты JavaScript.
ethane 27.01.2019 16:34

даже предоставление d3.json(./data.json) вызовет ту же проблему

user3755529 27.01.2019 16:40

Вы пробовали console.info(data[0])? Я думаю, это ваша проблема, так как это массив.

Sparlarva 27.01.2019 16:41

Дайте мне знать, если это работает, и я могу отправить его в качестве ответа :)

Sparlarva 27.01.2019 16:41

не повезло с данными [0], данные «не определены»

user3755529 27.01.2019 16:45
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
5
1 194
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

I wrote the following local server

Который выдает содержимое index.html в ответ на любой полученный запрос.

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

Итак, ваш JavaScript запрашивает data.json и получает содержимое index.html.

Поскольку содержимое index.html не является JSON и начинается с <, выдается сообщение об ошибке. Файл JSON не может начинаться с <.

Вам нужно исправить свой сервер, чтобы он давал браузеру то, что он запрашивает, вместо того, чтобы слепо отправлять index.html.

хорошо, это довольно сложно для меня, так как я на самом деле не разбираюсь в серверах node.js. Я не могу найти никакого руководства для Node.js, обслуживающего D3. Я думаю, что не стоит использовать node.js для запуска D3 для начинающих, возможно, мне следует придерживаться python.

user3755529 27.01.2019 17:28

Может быть, просто установите Apache HTTP, Lighttpd, Nginx или какой-нибудь другой распространенный HTTP-сервер вместо того, чтобы писать свой собственный.

Quentin 27.01.2019 17:31

да, это ответ, который я искал, я думаю, >python3 -m http.server< тоже выполняет эту работу

user3755529 27.01.2019 17:35

ваша проблема, похоже, в том, что ваш код не знает, как обслуживать что-либо, кроме index.html. Работать с чистым Node-сервером действительно неприятно, потому что большинство ресурсов в Интернете предполагают, что пользователи собираются использовать экспресс или другой фреймворк.

Ниже у меня есть сервер, который может обслуживать статические веб-сайты и обрабатывать запросы для нескольких распространенных типов мультимедиа. Вы можете добавить другие типы, изменив код в функции getContentType, найдя MIME-тип для этого формата файла.

надеюсь, это поможет

'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.info(`\t${request.method} Response: 404 Error, '${file}' Was Not Found!`);
        } else {
            response.writeHead(200, {'Content-Type': contentType})
                    .write(content);

            response.end();
            console.info(`\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.info(`\nPage Requested: ${request.url}\n`);
        } else {
            if (request.method == "GET") {
                console.info(`${request.method} Request: ${request.url}`);
            } else {
                console.info(`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.info(`Server running at ${hostname}:${port}\n`);
    });
}


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

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

Другие вопросы по теме