2017-09-15 80 views
1

我在理解为什么取指API不会让我发送POST请求到我的restify服务器时遇到一些主要问题。POST请求使用取指API无法正常工作

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

这条路线工作完全按预期如果我有邮差或HTTPRequester测试,但是当我再与获取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. 

两个问题

  1. 我特别在我的请求中使用了POSt方法,所以为什么突然选择OPTIONS?
  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) => { 
 
\t res.header('Access-Control-Allow-Origin', '*'); 
 
\t res.header('Access-Control-Allow-Headers', 'X-Requested-With'); 
 
\t 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的东西和加密/ 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; 
 
     }; 
 
    }); 
 
})();

回答

1

出现,因为的RESTify V5.x中所有CORS支持已经移动到this module

安装的RESTify-CORS中间件并添加以下到我的应用程序的工作:

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