Roblox中LocalScript使用HTTP请求的可行方案求助
Roblox获取玩家Marketplace库存的解决方案
问题背景
开发Roblox游戏时,需要通过HTTP请求获取玩家的Catalog/Marketplace库存(非游戏内库存),但LocalScript无法发起HTTP请求。将请求逻辑放入ModuleScript后,由于ModuleScript会继承调用它的脚本的权限限制,问题依然存在。
原ModuleScript代码:
local gearManagement = {} function gearManagement.GetGears(player) local HttpService = game:GetService("HttpService") local Table = "https://inventory.roproxy.com/v2/users/"..player.UserId.."/inventory?assetTypes=Gear&limit=100&sortOrder=Asc" local GearResponse = HttpService:RequestAsync({ Url = Table, Method = "GET" }); if GearResponse.Success then local TableBody = HttpService:JSONDecode(GearResponse.Body) for i, v in pairs(TableBody) do return v end end end function gearManagement.CheckForViewableInventory(player) local HttpService = game:GetService("HttpService") local CanSeeInventory = "https://inventory.roproxy.com/v1/users/"..player.UserId.."/can-view-inventory" local Response = HttpService:RequestAsync({ Url = CanSeeInventory, Method = "GET" }); end return gearManagement
原LocalScript代码:
local HttpService = game:GetService("HttpService") local players = game:GetService("Players") local player = players.LocalPlayer local serverStorage = game:GetService("ServerStorage") -- WHY THE HELL DOES THIS NOT WORK???????????? ITS RIGHT THERE GAME, THE UI FOLDER IS RIGHT THERE, WHY ARENT YOU SEEING IT -- ^i have found out how, local scripts can't interact w/ server stuff local gearCardBase = script.Parent.Parent.Parent.gearCard local gearManagement = require(script.Parent.gearManagement) local Response = gearManagement.CheckForViewableInventory(player) if Response.Success then -- If it doesnst work, then idk local Body = HttpService:JSONDecode(Response.Body) -- Decoding the table if Body.canView == true then -- Continue Code local Gears = gearManagement.GetGears(player) local gearRowNum = 0 if Gears ~= nil then -- Avoid errors for i, v in pairs(Gears) do -- print(v.name, v.assetId) local newGearCard = gearCardBase:Clone() newGearCard.Parent = script.Parent newGearCard.Visible = true newGearCard.Interactable = true local gearRowOffset = gearRowNum * 4 + 1 local trueI = i-gearRowOffset local xPositioningNum = 121 + 21 -- 2nd num is the space between the two cards local finalXPositioningNum = xPositioningNum * trueI newGearCard.Position.X = newGearCard.Position.X + finalXPositioningNum local yPositioningNum = 166 + 21 -- 2nd num is the space between the two cards local finalYPositioningNum = yPositioningNum * gearRowNum newGearCard.Position.Y = newGearCard.Position.Y + finalYPositioningNum newGearCard.gearImage.Image = "rbxthumb://type=Asset&w=150&h=150&id="..v.assetId end end else -- might put a warning here end end
核心解决方案
Roblox仅允许服务器端脚本调用HttpService发起HTTP请求,因此需要通过RemoteFunction实现客户端与服务器的通信:
- 服务器端脚本处理HTTP请求逻辑
- 客户端LocalScript通过RemoteFunction向服务器发起请求,获取数据后处理UI渲染
修正后的代码
1. 服务器端脚本(放入ServerScriptService)
local ReplicatedStorage = game:GetService("ReplicatedStorage") local HttpService = game:GetService("HttpService") local Players = game:GetService("Players") -- 创建RemoteFunction,用于客户端-服务器通信 local InventoryRemote = Instance.new("RemoteFunction") InventoryRemote.Name = "InventoryRemote" InventoryRemote.Parent = ReplicatedStorage -- 处理客户端的库存请求 function InventoryRemote:OnServerInvoke(player) -- 检查库存是否可见 local canSeeUrl = string.format("https://inventory.roproxy.com/v1/users/%d/can-view-inventory", player.UserId) local visibilityResponse = HttpService:RequestAsync({ Url = canSeeUrl, Method = "GET" }) if not visibilityResponse.Success then return false, "无法检查库存可见性" end local visibilityData = HttpService:JSONDecode(visibilityResponse.Body) if not visibilityData.canView then return false, "玩家库存为私有状态" end -- 获取Gear类型库存 local gearUrl = string.format("https://inventory.roproxy.com/v2/users/%d/inventory?assetTypes=Gear&limit=100&sortOrder=Asc", player.UserId) local gearResponse = HttpService:RequestAsync({ Url = gearUrl, Method = "GET" }) if gearResponse.Success then return true, HttpService:JSONDecode(gearResponse.Body) else return false, "获取Gear库存失败" end end
2. 客户端LocalScript(UI相关位置)
local ReplicatedStorage = game:GetService("ReplicatedStorage") local Players = game:GetService("Players") local player = Players.LocalPlayer local gearCardBase = script.Parent.Parent.Parent.gearCard local InventoryRemote = ReplicatedStorage:WaitForChild("InventoryRemote") -- 调用服务器端接口,用pcall捕获网络错误 local success, result = pcall(function() return InventoryRemote:InvokeServer() end) if success then local canView, gearData = result if canView then local gearRowNum = 0 for i, gear in ipairs(gearData) do -- 克隆并配置Gear卡片 local newGearCard = gearCardBase:Clone() newGearCard.Parent = script.Parent newGearCard.Visible = true newGearCard.Interactable = true -- 计算卡片位置(每行4个) local gearIndexInRow = (i - 1) % 4 local xSpacing = 121 + 21 -- 卡片宽度 + 间距 local ySpacing = 166 + 21 -- 卡片高度 + 间距 newGearCard.Position = UDim2.new( 0, 121 + (xSpacing * gearIndexInRow), 0, 166 + (ySpacing * gearRowNum) ) -- 设置Gear图标 newGearCard.gearImage.Image = string.format("rbxthumb://type=Asset&w=150&h=150&id=%d", gear.assetId) -- 每4个卡片切换到下一行 if gearIndexInRow == 3 then gearRowNum += 1 end end else -- 库存不可见时的处理 warn(result) end else -- 请求出错时的处理 warn("请求失败:", result) end
关键说明
- 权限问题解决:所有HTTP请求移至服务器端脚本,避开LocalScript的权限限制
- 数据安全:Roblox会自动验证RemoteFunction的调用者身份,防止恶意请求
- 错误处理:用
pcall包裹InvokeServer,处理网络波动或服务器错误 - 排版逻辑优化:修正原代码中的索引计算错误,实现每行4个卡片的规整布局
内容的提问来源于stack exchange,提问作者TheLemon27
相关产品推荐
相关产品推荐

