пытаясь изучить 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(./data.json) вызовет ту же проблему
Вы пробовали console.info(data[0])? Я думаю, это ваша проблема, так как это массив.
Дайте мне знать, если это работает, и я могу отправить его в качестве ответа :)
не повезло с данными [0], данные «не определены»



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


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.
Может быть, просто установите Apache HTTP, Lighttpd, Nginx или какой-нибудь другой распространенный HTTP-сервер вместо того, чтобы писать свой собственный.
да, это ответ, который я искал, я думаю, >python3 -m http.server< тоже выполняет эту работу
ваша проблема, похоже, в том, что ваш код не знает, как обслуживать что-либо, кроме 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);
})();
d3.jsonожидает правильного синтаксисаjson, а не объектов JavaScript. Learnjsdata.com/read_data.html. Это не работает, потому что вы анализируетеjsonв объекты JavaScript.