Ответ является либо пустым объектом, либо неожиданным токеном <в JSON в позиции 0 от Nodejs - PullRequest
0 голосов
/ 09 июня 2019

Я тестирую с каким-то поддельным файлом JSON в одностраничном приложении, но я всегда получаю неожиданный токен <в JSON в позиции 0 </strong> или пустой объект , если я используюJSON.stringify () по моему обещанию возврата.Я не уверен, почему это происходит, и я боролся с этим в течение двух дней.Я что-то упустил?

Моя файловая структура выглядит следующим образом:

-server
 -client
  -action
   -movies.js
 -route
  -fakeData.json
  -movieList.js
 -index.js

Когда я использую POSTMAN, я вижу возвращаемый объект, а когда я проверяю браузер на вкладке сети, я могусмотрите запрос, и он возвращает статус (200).Я делаю это с Redux-thunk, а также с библиотекой http-proxy-middleware, чтобы они могли общаться

fakeData.json ::

{
    "movies": [
        {
            "name": "test1",
            "url": "https://example1.com"
        },
        {
            "name": "test2",
            "url": "https://example2.com"
        }
    ]
}

movieList.js:

const characters = require('../FakeData/characters.json');

// reads the file synchronously
var fs = require("fs");

module.exports = (app) => {
    app.get('/api/characters', (req, res) => {

        const fileContents = fs.readFileSync(__dirname+'/characters.json', 'utf8')

        try {
            const data = JSON.parse(fileContents)
            res.json({data})
        } catch(err) {
            console.error(err)
        }
        // res.json(characters)
    });
}

index.js:

const express = require('express');
const bodyParser = require('body-parser');

const app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));

require('./routes/movieList')(app);

if (process.env.NODE_ENV === 'production') {
    // Express will server up production assets like main.css or main.js
    app.use(express.static('client/build'));

    const path = require('path');
    // Express serves up index.html if it doesn't recognize the route
    app.get('/', (req, res) => { // Catch the rest
        res.sendFile(path.resolve(__dirname, 'client', 'build', 'index.html'));

    });
}

const PORT = process.env.PORT || 5000;

app.listen(PORT)

movies.js:


export const FETCH_CHAR = "fetch_character";
export const SET_CHARS = "set_characters";

function handleResponse(response) {
    if(response.ok) {
        return response.json()
    } else {
        let error = new Error(response.statusText);
        error.response = response;
        throw error;
    }
}

export function setMovies(characters) {
    return {
        type: SET_CHARS,
        characters
    }
}

export function fetchChars() {
    return dispatch => {
        fetch('/api/characters')
        .then(res => {
            // return res.text()  **When I try res.text(), I got html response
            return res.json()    **This gives me Unexpected token < in JSON at position 0
        })
        .then(data => dispatch(setMovies(data.characters)))
    }
}

Это то, что я настроил в моем React прокси, если вам интересно:

const proxy = require('http-proxy-middleware');

module.exports = function(app) {
    app.use(proxy('/api/*', { target: 'http://localhost:5000' , changeOrigin: true }));
};

Я думаю, что после того, как я получу данные из фальшивого JSON-файла, я смогу выполнить с ним больше действий, например, показать данные фильмов, потому что я вызываю этот вызов API сразу после подключения кодаDOM.

Редактировать В моем movieList.js я пытался использовать:

try {
    const data = JSON.parse(fileContents)
    res.json({ foo: data })
} catch(err) {
    console.error(err)
}

, а в movies.js я пытаюсь вернуть res вместо res.json (), потому что я получу неожиданный токен <в JSON в позиции 0, и на моей вкладке сети инструмента dev для ответа я получу следующее: </p>

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <link rel="shortcut icon" href="/favicon.ico" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta name="theme-color" content="#000000" />
    <!--
      manifest.json provides metadata used when your web app is installed on a
      user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
    -->
    <link rel="manifest" href="/manifest.json" />
    <!--
      Notice the use of  in the tags above.
      It will be replaced with the URL of the `public` folder during the build.
      Only files inside the `public` folder can be referenced from the HTML.

      Unlike "/favicon.ico" or "favicon.ico", "/favicon.ico" will
      work correctly both with client-side routing and a non-root public URL.
      Learn how to configure a non-root public URL by running `npm run build`.
    -->
    <title>React App</title>
  </head>
  <body>
    <style>
      html {
          height: 100%;
          min-height: 100%;
          position: relative;
          /* height: 100vh; */
          margin: 0;
          /* overflow:auto; */
      }
      body {
          height: 100%;
          position: relative;
      }
      #root {
          height: 100%;
          /* height: 100vh; */
      }
    </style>
    <div id="root"></div>
    <!--
      This HTML file is a template.
      If you open it directly in the browser, you will see an empty page.

      You can add webfonts, meta tags, or analytics to this file.
      The build step will place the bundled scripts into the <body> tag.

      To begin the development, run `npm start` or `yarn start`.
      To create a production bundle, use `npm run build` or `yarn build`.
    -->
  <script src="/static/js/bundle.js"></script><script src="/static/js/1.chunk.js"></script><script src="/static/js/main.chunk.js"></script><script src="/main.8c1de248b2f13e929d84.hot-update.js"></script></body>
</html>

Ответы [ 2 ]

0 голосов
/ 09 июня 2019

Если вы пытаетесь создать фиктивные данные с сервера, почему бы не создать переменную, которая является json, и экспортировать ее?

Проблема, которая возникает, исходя из моего опыта, заключается в том, что вы отправляете строку, а клиент ожидает JSON.

Попробуйте что-то вроде:

fakeData.js:

const fake = {
"movies": [
    {
        "name": "test1",
        "url": "https://example1.com"
    },
    {
        "name": "test2",
        "url": "https://example2.com"
    }
   ]
  }

module.exports = fake

А в movieList.js:

const characters = require('./whatever-path/fakeData.js');

module.exports = (app) => {
    app.get('/api/characters', (req, res) => {
       res.json({characters})
    });
}

Надеюсь, что это работает!

0 голосов
/ 09 июня 2019

Вам не нужны скобки в вашем ответе.

.then(response =>  response.json())
.then(data => console.log(data))
...