POST 请求通过 Fetch 重新验证 API 不工作
POST request to restify with Fetch API not working
我在理解为什么 Fetch API 不允许我向我的 restify 服务器发送 POST 请求时遇到一些重大问题。
我有一个基本的 restify 服务器,其路由接收 /login
上的 POST 请求。
如果我使用 Postman 或 HTTPRequester 进行测试,此路由将按预期完美运行,但是当我随后使用 fetch API 在浏览器应用程序上对其进行测试时,我收到以下错误(在 Chrome ):
OPTIONS http://localhost:1337/login 405 (Method Not Allowed)
Fetch API cannot load http://localhost:1337/login. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access. The response had HTTP status code 405. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
两期
- 我在请求中专门使用了POSt方法,为什么突然OPTIONS?
- 我已经在我的服务器上设置了
Access-Control-Allow-Origin: *
。
编辑:我使用 restify v5.2.0
我的服务器应用:
const restify = require('restify');
const app = restify.createServer({
'name': 'API Token Test',
'version': '1.0.0'
});
app.use(restify.plugins.acceptParser(app.acceptable));
app.use(restify.plugins.bodyParser());
app.use(restify.plugins.jsonp());
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Headers', 'X-Requested-With');
return next();
});
app.post('/login', (req, res) => {
db.execute('SELECT idusers, password FROM users WHERE username = ?', [req.body.username], (selError, rows) => {
if (passwordHash.verify(req.body.password, rows[0].password)) {
crypto.randomBytes(256, (err, buf) => {
if (err) return res.status(500).end();
else {
const token = buf.toString('hex');
db.execute('INSERT INTO accesstokens SET userid = ?, token = ?', [rows[0].idusers, token], (insError) => {
if (insError) return res.status(500).end();
else return res.send({ "AccessToken": token });
});
}
});
} else {
res.status(401).end();
}
});
});
app.listen(1337);
(我省略了 mysql 东西和 crypto/password-hash -requires,它们与问题无关)
我的客户端脚本:
(() => {
document.addEventListener('DOMContentLoaded', () => {
const form = document.querySelector('.loginForm');
form.onsubmit = () => {
const data = JSON.stringify({
'username': form.username.value,
'password': form.password.value
});
let headers = new Headers();
headers.set('Accept', 'application/json');
headers.set('Content-Type', 'application/json');
headers.set('Content-Length', data.length);
fetch('http://localhost:1337/login', {
'method': 'POST',
'headers': headers,
'mode': 'cors',
'cache': 'default',
'body': data
})
.then((result) => result.json())
.then((data) => {
console.log(data);
localStorage.setItem('token', data);
})
.catch((err) => {
console.log(err);
});
return false;
};
});
})();
似乎所有 CORS 支持都已移至 this module,因为 restify v5.x。
安装 restify-cors-middleware 并将以下内容添加到我的应用程序有效:
const corsMiddleware = require('restify-cors-middleware');
const cors = corsMiddleware({
'origins': ['*']
});
app.pre(cors.preflight);
app.use(cors.actual);
我在理解为什么 Fetch API 不允许我向我的 restify 服务器发送 POST 请求时遇到一些重大问题。
我有一个基本的 restify 服务器,其路由接收 /login
上的 POST 请求。
如果我使用 Postman 或 HTTPRequester 进行测试,此路由将按预期完美运行,但是当我随后使用 fetch API 在浏览器应用程序上对其进行测试时,我收到以下错误(在 Chrome ):
OPTIONS http://localhost:1337/login 405 (Method Not Allowed)
Fetch API cannot load http://localhost:1337/login. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access. The response had HTTP status code 405. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
两期
- 我在请求中专门使用了POSt方法,为什么突然OPTIONS?
- 我已经在我的服务器上设置了
Access-Control-Allow-Origin: *
。
编辑:我使用 restify v5.2.0
我的服务器应用:
const restify = require('restify');
const app = restify.createServer({
'name': 'API Token Test',
'version': '1.0.0'
});
app.use(restify.plugins.acceptParser(app.acceptable));
app.use(restify.plugins.bodyParser());
app.use(restify.plugins.jsonp());
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Headers', 'X-Requested-With');
return next();
});
app.post('/login', (req, res) => {
db.execute('SELECT idusers, password FROM users WHERE username = ?', [req.body.username], (selError, rows) => {
if (passwordHash.verify(req.body.password, rows[0].password)) {
crypto.randomBytes(256, (err, buf) => {
if (err) return res.status(500).end();
else {
const token = buf.toString('hex');
db.execute('INSERT INTO accesstokens SET userid = ?, token = ?', [rows[0].idusers, token], (insError) => {
if (insError) return res.status(500).end();
else return res.send({ "AccessToken": token });
});
}
});
} else {
res.status(401).end();
}
});
});
app.listen(1337);
(我省略了 mysql 东西和 crypto/password-hash -requires,它们与问题无关)
我的客户端脚本:
(() => {
document.addEventListener('DOMContentLoaded', () => {
const form = document.querySelector('.loginForm');
form.onsubmit = () => {
const data = JSON.stringify({
'username': form.username.value,
'password': form.password.value
});
let headers = new Headers();
headers.set('Accept', 'application/json');
headers.set('Content-Type', 'application/json');
headers.set('Content-Length', data.length);
fetch('http://localhost:1337/login', {
'method': 'POST',
'headers': headers,
'mode': 'cors',
'cache': 'default',
'body': data
})
.then((result) => result.json())
.then((data) => {
console.log(data);
localStorage.setItem('token', data);
})
.catch((err) => {
console.log(err);
});
return false;
};
});
})();
似乎所有 CORS 支持都已移至 this module,因为 restify v5.x。
安装 restify-cors-middleware 并将以下内容添加到我的应用程序有效:
const corsMiddleware = require('restify-cors-middleware');
const cors = corsMiddleware({
'origins': ['*']
});
app.pre(cors.preflight);
app.use(cors.actual);