POST请求使用Fetch API无法正常工作

我有一些重大的问题,理解为什么Fetch API不会让我发送POST请求到我的restify服务器。

我有一个基本的restify服务器,在/login上接收POST请求的路由。

如果我使用Postman或HTTPRequester进行testing,但是当我使用获取API在浏览器应用程序上对其进行testing时,此路由完全按照预期运行,但出现以下错误(在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. 

两个问题

  1. 我在我的请求中特别使用了POSt方法,那么为什么突然select?
  2. 我已经在我的服务器上设置了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的东西和encryption/密码散列需求,这是不相关的问题)

而我的客户端脚本

 (() => { 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; }; }); })(); 

自restify v5.x以来,所有的CORS支持都已经移到了这个模块中 。

安装restify-cors-middleware并将以下内容添加到我的应用程序中:

 const corsMiddleware = require('restify-cors-middleware'); const cors = corsMiddleware({ 'origins': ['*'] }); app.pre(cors.preflight); app.use(cors.actual);