Meteor:从客户端访问函数,在服务器上运行
我正在尝试创建一个使用Steam API的程序。我希望能够调用该方法从客户机检索用户信息,同时对客户机保密该方法的实际代码,因为它包含一个API密钥。我尝试在服务器文件夹中将这些方法定义为全局方法,如下所示:Meteor:从客户端访问函数,在服务器上运行,meteor,methods,public,Meteor,Methods,Public,我正在尝试创建一个使用Steam API的程序。我希望能够调用该方法从客户机检索用户信息,同时对客户机保密该方法的实际代码,因为它包含一个API密钥。我尝试在服务器文件夹中将这些方法定义为全局方法,如下所示: key = 'xxxxxxxxxxxxxxxx'; Meteor.steamFunctions = { getName: function(user){ var userSteamId = user.profile.id; Meteor.http.
key = 'xxxxxxxxxxxxxxxx';
Meteor.steamFunctions = {
getName: function(user){
var userSteamId = user.profile.id;
Meteor.http.get('http://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0002/?key=' + key + '&steamids=' + userSteamId, function(error, resultJSON){
if (error){
return 'Error in Steam API';
} else {
var json = JSON.parse(resultJSON);
return json.personaname;
}
})
},
getPic: function(user){
var userSteamId = user.profile.id;
Meteor.http.get('http://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0002/?key=' + key + '&steamids=' + userSteamId, function(error, resultJSON){
if (error){
return 'Error in Steam API';
} else {
var json = JSON.parse(resultJSON);
return json.avatarfull;
}
})
}
}
然后,我尝试在客户端脚本中这样调用它:
if (Meteor.isClient){
Template.profile.helpers({
'getName': function(){
return Meteor.steamFunctions.getName(Meteor.user());
}
});
}
然而,这会让人感到失望
Exception in template helper: TypeError: Cannot read property 'getName' of undefined
at Object.Template.profile.helpers.getName
在仍然访问数据的情况下,如何对用户保密?好吧,这并不像向Meteor全局添加属性那么简单。此外,执行此操作的远程方法/调用API将涉及异步代码 在服务器端,以仅在服务器上可见的代码(例如,
/server
子目录)使用机密API密钥对API进行调用。在服务器端定义可在客户端调用的
在服务器端Meteor方法中,您可以检查登录的用户或用户ID,并使用它来决定是进行调用还是忽略请求。如果请求不正确或出现错误,您可以从服务器端抛出一个新的Meteor.Error,但这需要资源进行通信
关于Meteor,需要了解的是,改变Javascript在浏览器或服务器上的行为并没有什么神奇之处。服务器最终运行的是nodejs。服务器上定义的对象不会神奇地迁移到客户端,反之亦然。如果一个对象是在这两者上定义的,那么它实际上是两段独立的代码
因此,在客户端代码中,Meteor.call
从浏览器调用服务器端代码。。。实际上使用的是一个现有的websocket或ajax API,本质上是异步的。这意味着您需要构造客户端代码,以便在浏览器上提供回调函数,以处理查找Name
或Pic
的异步返回结果。直接返回和命令式编码样式是不可能的
通常,您需要根据查找返回的信息更新用户屏幕上的某些内容。通常的Meteor编码是使用Session.set()
更新回调函数。模板可以引用这些会话变量,并通过隐式或显式Tracker.autorun()在API返回数据时更新屏幕。您需要:
蒸汽函数
移动到其中const KEY='xxxxxxxxxxxxxx';
常量URL=http://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0002';
流星法({
getName(){
const userSteamId=Meteor.user().profile.id;
常量参数={
钥匙:钥匙,
streamid:userstreamid,
};
试一试{
var result=HTTP.get(URL,{params});
//仔细检查这个-我不知道这个API返回了什么
//您需要的数据可以嵌套在结果下,如result.data或其他内容。
返回JSON.parse(result.PersonalName);
}捕获(e){
//发生了一些不好的事情-可能会抛出一个错误。
返回false;
}
},
});
注意此方法是在服务器上定义的,因此我们不会将键
公开给客户端。还要注意,我们使用的是HTTPapi的同步版本,因此可以将值返回给客户端
client/lib/user.js
Tracker.autorun(函数(){
user=Meteor.user();
if(user&&user.profile&&user.profile.id){
Meteor.call('getName',(err,name)=>{
Session.set('streamname',name);
});
}否则{
Session.set('streamname','');
}
});
更新用户日志时,获取steam名称并设置全局会话变量
client/templates/profile.js
Template.profile.helpers({
getName:函数(){
return Session.get('streamname');
},
});
阅读模板中使用的steamName
会话变量。感谢您的回复。。。我现在的问题是,该方法是在用户实际“登录”之前从客户端调用的,因此给了我一个“无法从未定义访问”错误。。我尝试在iron router文件中使用waitOn Meteor.user(),我还尝试安装fast render。。。两者似乎都不起作用。你知道一种更简单的方法来完成等待吗?不管怎样,谢谢你的回答,我真的很感激:)是的,这应该是一个简单的解决办法。在我添加它之前,您能告诉我steam名称何时更改以及概要文件模板何时呈现吗?例如,如果名称从未更改,并且配置文件被大量呈现,那么您将进行大量不必要的调用。在这种情况下,它应该是全局设置的。所以。。。我走了另一条路,我不确定这条路是否可行/正确。我在考虑创建一个集合,其中包含所有信息,信息被插入onCreateUser(),并在每次使用onLogin()登录时调用和更新信息。。。然后让他们通过收集访问数据。然而,我不确定这是否是完成任务的最佳方式。你对此有什么意见吗?对不起,我想带你去兜风。。。我只是不知道最好的方法:)有很多方法可以解决这个问题。您的建议听起来不错,但您可能希望直接写入用户的文档,而不是使用另一个集合-我想这取决于需要的数据量和内容。我用一个使用全局自动运行和会话变量的示例更新了答案。这是一个简单的解决方案,应该在适当的时候更新。唯一一次我不想