#express #fetch
Вопрос:
Я пытаюсь сделать запрос на получение защищенного маршрута в своем приложении Express. Маршрут работает нормально, когда запрос сделан почтальоном, я получаю отправленный ответ. Но когда я пытаюсь выполнить запрос на извлечение из интерфейса, я получаю SyntaxError: Unexpected token A in JSON at position 0
.
Запрос на извлечение из интерфейса
export const getProtectedMessage = async (token) => {
const URI = 'http://localhost:3001'; //TODO save root uri to environment variable
const bearer = 'Bearer ' token;
return fetch(`${URI}/me`, {
method: 'GET',
withCredentials: true,
credentials: 'include',
headers: {
'Authorization': bearer,
'Content-Type': 'application/json',
'Cache-Control': 'no-cache'
}
})
.then(handleErrors)
.then((res) => res.json())
.catch((err) => {
console.error(err);
});
};
Точка входа для экспресс-приложения index.js
import dotenv from 'dotenv';
import express from 'express';
import morgan from 'morgan';
import cors from 'cors';
import routes from './routes/index.js';
import db from './db/index.js';
dotenv.config();
db(process.env.DB_NAME);
const PORT = process.env.PORT || 3001;
const app = express();
app.use(express.json());
app.use(cors({ credentials: true, origin: 'http://localhost:3000' }));
app.use(morgan('dev'));
app.use(routes);
app.get('*', (req, res) => {
res.sendStatus(404);
});
app.listen(process.env.PORT, () => {
console.log(`app listening on port ${PORT}`);
});
Маршруты
import express from 'express';
import * as auth from '../controllers/auth.js';
import expressjwt from 'express-jwt';
import dotenv from 'dotenv';
dotenv.config();
const router = express.Router();
const jwtCheck = expressjwt({
secret: process.env.SECRET_KEY,
algorithms: ['sha1', 'RS256', 'HS256']
});
router.post('/sign-up', auth.signUp);
router.post('/sign-in', auth.signIn);
router.get('/me', jwtCheck, auth.profile);
export default router;
Контроллер для защищенного маршрута
export function profile(req, res) {
res.status(200).send('A secret resource - only for authenticated users');
}
Комментарии:
1. Вы отправляете строку(
res.status(200).send('A secret resource - only for authenticated users');
) со своего сервера, и на стороне интерфейса вы пытаетесь проанализировать ее в json(res.json()
. что является ошибкой.2. Попробуйте это —
res.status(200).json({screct:"##########"})
3. @GulamHussain Спасибо! Я обновил свой ответ 🙂
Ответ №1:
В конце концов ошибка заключалась в том, как я отправлял ответ. Может быть, есть более подходящий способ сделать это, но замена контроллера на следующий сработала.
export function profile(req, res) {
// res.status(200).send('A secret resource - only for authenticated users'); // WRONG
res.status(200).json('Resource only for authenticated users'); // works!
}
Еще одна вещь, также рекомендуется проверять заголовок приложения в запросе на выборку. Иногда вы не знаете, что получаете от бэкенда, может быть json, может быть текст.
export const getProtectedMessage = async (token) => {
const URI = 'http://localhost:3001'; //TODO save root uri to environment variable
const bearer = 'Bearer ' token;
return fetch(`${URI}/me`, {
method: 'GET',
withCredentials: true,
credentials: 'include',
headers: {
Authorization: bearer,
'Content-Type': 'application/json',
'Cache-Control': 'no-cache'
}
})
.then(handleErrors)
.then((res) => {
const contentType = res.headers.get('Content-Type').split(';')[0];
if (contentType === 'application/json') {
return res.json();
}
console.log(contentType);
if (contentType === 'text/html') {
return res.text();
}
})
.catch((err) => {
console.error(err);
});
};