2017-09-13 65 views
0

我使用Meteor做web应用程序,想法是我们拥有客户端的所有功能,并且客户端会对我们的REST API执行API调用。问题是我不管理向我们的API服务器发送任何HTTPS POST请求。互联网充斥着说CORS头文件存在问题的帖子,但API服务器发送头文件:access-control-allow-origin:*。所以这不应该是问题。使客户端只使用流星的POST请求到第三方API

我有简单的登录模板,该模板我会抓住这个提交事件:

import {Template} from 'meteor/templating'; 
import { HTTP } from 'meteor/http'; 
import "./login.html"; 

Template.login.events({ 
    'submit .login_form'(event) { 
     const target = event.target; 
     let username = target.username.value; 
     let password = target.password.value; 

     // attempted HTTPS POST request 
     // Meteor.http.post(my_api_url, { // no success with this either 
     HTTP.call("POST", my_api_url, { 
      data: { 
       method: "login", 
       params: { 
        username: username, 
        passwrd: password 
       } 
      } 
     }, function (error, result) { 
      // we will end up here just fine, but 'error' contains error 
      // result is undefined 
      console.log(error); 
     }); 
    // do stuff 
    }, 
}); 

的console.log(结果)给了我这个错误:

Error: network 
Stack trace: 
httpcall_client.js/HTTP.call/[email protected]://localhost:3000/packages/http.js?hash=2a49...181ea:243:20 

是的,我已经用邮递员测试了API,它应该返回上面显示的数据。我在本地主机上运行Meteor应用程序。

编辑: 的JSON我试图传递给API是

{"method": "login", 
"params": {"username": "username", 
"passwrd": "password"}} 

编辑2: 当在浏览器的网络选项卡来看,我看不出有什么走出去请求。

我的流星模板看起来是这样的:

<template name="login"> 
    <h1>Login</h1> 
    <form class="login_form" method="POST"> 
     <input type="text" name="username" placeholder="Username"/> 
     <input type="password" name="password" placeholder="Password"/> 
     <input class="btn btn-success" type="submit" value="Log In"/> 
    </form> 
</template> 
+0

什么是你的'my_api_url'的价值? – Styx

+0

它是流星的全局变量,字符串。 https://myurl.foo/api。不能透露真实的网址 –

+0

好吧,你可以在做你的请求之前'console.log'这个变量吗?所以你会确定它是正确的。 – Styx

回答

0

我不得不在开始添加功能

Template.login.events({ 
    'submit .login_form'(event) { 
     event.preventDefault(); 

event.preventDefault();线我已经阻止执行POST请求我的流星应用程序客户端之后,浏览器开始发送OPTIONS请求API服务器。但是这并没有完全解决问题。

然后问题是流星在3000端口运行,并且API服务器设置CORS头:access-control-allow-origin:http://localhost,留下端口号,这就是为什么所有客户端请求都失败时在本地主机上运行Meteor应用程序。当使用postman/cURL测试请求时,access-control-allow-origin头始终设置为*,浏览器发送请求时不会出现这种情况。

安装lighttpd并将其设置为反向代理以在端口80中运行meteor应用程序,然后在etc/hosts文件中为ip 127.0.0.1添加新主机名。 “127.0.0.1 localhost mymeteor.app”解决了我的问题。现在我必须通过url mymeteor.app访问我的Meteor应用程序,它可以工作。

链接配置lighttpd的为代理:https://redmine.lighttpd.net/projects/1/wiki/Docs_ModProxy

+0

在你的问题中,你声明你的API服务器具有'Access-Control-Allow-Origin:*',现在 - 它具有'http:// localhost'而不是'*'。它与端口无关,因为它的*起源*。如果你的API服务器与'*'有所不同,那么你必须在你的请求中指定'Origin:...'标头。所以这个问题可以在不安装http代理服务器的情况下解决 – Styx

+0

如果API服务器接受请求中定义的来源并且信任它,那么这不是安全问题吗? (至少当请求来自浏览器时?) –

+0

它是这样定义的。浏览器用'OPTIONS'请求发送'Origin:...'头,并查看它从API服务接收到的内容。基于此响应浏览器允许(或不)您的请求在JavaScript中。无论使用什么端口访问API服务,只有_origin_很重要。 – Styx

0

我错了,还是不应该回调是:

function (error, result) { 
    //... 
} 

编辑:我没有错:还检查docs中,例如那里也使用上面所示的样式中的回调。

这至少会解释为什么结果是一个错误。 (它不能解释为什么你的http调用本身返回一个错误)。

编辑2:我在这里看到更多的陷阱。

看那options对象结构:

{ 
    method: "POST", 
    params: { 
     username: username, 
     passwrd: password 
    } 
} 

也可以是:

{ 
    method: "POST", 
    data: { 
     username: username, 
     passwrd: password 
    } 
} 

根据您的网络服务要求。那么有关于password的一点 - 这是打算还是错字?

那么关于使用auth

{ 
    method: "POST", 
    params: { // or data...? 
     username: username, 
     passwrd: password 
    }, 
    auth: username+":"+password 
} 

这似乎只是一个配置问题,根据您的Web服务的要求。尝试不同的选项配置。必须有一个解决方案。

您可以添加手动调用Web服务的方式吗?

+0

我也试过,在这种情况下结果是未定义的,错误包含错误 –

+0

那么这是正确的行为,因为错误时回调应该包含未定义的结果参数并且错误存储在错误中参数。在结果上,回调应该包含一个未定义的错误和结果。 – Jankapunkt

+0

正确的行为是的,但没有解释为什么我不能发布POST请求? –

1

似乎你在服务器端有错误。

根据http package source codenetwork错误只有在请求已完成但没有http回答时才会被抛出(传递给回调)。因此,这不是一个客户问题。

相关问题