Node.js: ошибка пути при загрузке файла JSON с помощью экспресс - PullRequest
0 голосов
/ 05 мая 2018

У меня есть набор папок и файлов, созданных таким образом:

viz
|_ app.js // node application
|_ public
        |_ css
                |_ bubblemap.css
        |_ images
        |_ nuts
                |_ nuts0.json
        |_ script
                |_ bubblemap.js
|_ views
        |_ bubblemap.hbs

bubblemap.hbs

<html lang='en'>
    <head>
        <meta charset='utf-8'>
        <title>Bubblemap</title>
        <script src='https://d3js.org/d3.v5.js' charset='utf-8'></script>
        <link href='/css/bubblemap.css' rel='stylesheet'/>
    </head>

    <body>
    </body>

    <script> 
        var viewData = {}; 
        viewData.dataHome = JSON.parse('{{json dataHome }}'.replace(/&quot;/g, '"').replace(/&lt;/, ''));
        viewData.dataWork = JSON.parse('{{json dataWork}}'.replace(/&quot;/g, '"').replace(/&lt;/, ''));    
    </script>

    <script src='/script/bubblemap.js' rel='script'/><{{!}}/script>
</html>

bubblemap.js

(function() {
    var files = ['../nuts/nuts0.json', '../nuts/nuts2.json'];
    var promises = [];

    promises.push(d3.json(files[0]));
    promises.push(d3.json(files[1]));

    Promise.all(promises)
        .then(makeBubblemap)
        .catch(function(err) {
            console.log('Error loading files!');
            throw err;
        });

    function makeBubblemap(data) {
        var nuts0 = data[0];
        var nuts2 = data[1];
        var home = viewData.dataHome;
        var work = viewData.dataWork;
    }
)

И это файл приложения узла.

а именно / app.js

// import...
var app = express();
const webapp_options = {'port': 3000};
initialize();

async function initialize() {
    await postgreSQLlib.connect();

    app.set('views', '' + __dirname + '/views'); 
    app.use(express.static(__dirname + '/public')); 
    app.set('view engine', 'hbs'); 
    app.engine('hbs', hbs.__express); 

    hbs.registerHelper('json', function(context) {
        return JSON.stringify(context);
    });

    app.get('/bubblemap', bubblemap);

    app.listen(webapp_options.port, function() {
        console.log('Ready & listening on http://localhost:' + webapp_options.port + '/');
    });
}

async function bubblemap(req, res) {
    // download data from db
    var dataWork = await postgreSQLlib.getTableHome();
    var dataHome = await postgreSQLlib.getTableWork();

    // create and fill object to pass to view
    var viewData = {}; 
    viewData.dataWork = dataWork;
    viewData.dataHome = dataHome;

    // pass data to view
    res.render('bubblemap', viewData);
}

Я получаю эту ошибку:

Ошибка загрузки файлов! Ошибка: 404 не найден

То есть файлы nuts0 и nuts2 подобраны неправильно. Я думаю, что это проблема пути, но мне она кажется правильной.

Я пытаюсь: ../nuts/nuts0.json, ./nuts/nuts0.json, nuts/nuts0.json, но ничего не работает.

1 Ответ

0 голосов
/ 05 мая 2018

Проблема в том, что ресурс, вероятно, не может быть загружен из-за того, что веб-приложение не обслуживает его ... Это можно доказать, попытавшись получить доступ к URL-адресу файла json.

Тогда все зависит от того, как вы хотите служить JSON:

Filesystem

· Serve Static : /public/file.json

В этом примере у вас будут файлы в общедоступной папке, и они будут служить статическим содержимым файловой системы.

app.use(express.static('public'))

Сделайте папку с именем public и сохраните jsons внутри, они будут доступны в корне веб-приложения localhost:3000/nuts0.json Подробнее об обслуживании статических файлов в экспрессе

· Send File : /private/file.json

В этом примере у вас все еще есть JSON в виде файла в файловой системе, но не в общедоступной (общедоступной) папке (как в примере выше). Вместо этого здесь вы используете его в качестве ресурса в пути к маршрутизатору (запрос GET), и вы можете даже применить предварительные проверки (если запрос требует файлы cookie, параметры, ...)

app.get("/jsonFiles/nut0.json",(req,res)=>{
 res.sendFile(__dirname+"/private/nuts0.json")
})

Подробнее о экспресс: sendFile

Динамически генерируется по запросу GET

В этом примере у вас нет файла в вашей файловой системе, но вы создаете его в реальном времени по запросу (из базы данных, памяти, ...) Вы также можете применить предварительные проверки (есть ли у пользователя необходимые разрешения, файлы cookie, параметры запроса и т. Д.)

global.example_counter = 0; //in memory (global) variable
app.get("/jsonFiles/a-virtual-path-for-the-json",(req,res)=>{
 example_request_counter++
 res.json({"total requests":example_request_counter})
})

«jsonFiles» не должен существовать, то есть путь к маршрутизатору веб-приложения в конце, то, что обслуживается, это то, что находится в res.send / res.json

global.inMemoryDB = { //in memory (global) variable
 "nuts0":{"data":"the universe is in fact a multiverse"},
 "nuts1":{"data":"tesla was bright"},
 "nuts2":{"data":"sugar kills..."},
}; 
//router path
app.get("/jsonFiles/:j",(req,res)=>{
 if(inMemoryDB[req.params.j]){res.json(inMemoryDB[req.params.j])}
 else{res.json({"error":"non-existing virtual file requested"}
)}
// http://localhost:3000/jsonFiles/nuts0 will serve you the inMemory json

Подробнее о req.params (Express API Doc)


Лично, в основном для производства, я бы использовал NGINX в качестве обратного прокси для ваших приложений node.js и вместо этого передавал статический контент.

...