从 Expo App 调用本地托管服务器

Posted

技术标签:

【中文标题】从 Expo App 调用本地托管服务器【英文标题】:Calling locally hosted server from Expo App 【发布时间】:2022-01-13 22:16:15 【问题描述】:

我正在创建一个 react-native 应用程序,我创建的其中一个组件包含一个属性,该属性是通过来自 http 请求的数据填充的。

现在我正在通过笔记本电脑托管服务器,但我正在使用 Expo 应用程序在手机上测试该应用程序。由于这是两个独立的设备,http://localhost:3000 调用不起作用,因此我无法判断我的组件是否正常工作。

我有什么方法可以在我的笔记本电脑上运行服务器并进行设置,以便 Expo 应用程序中的 http 请求到达服务器?

【问题讨论】:

你搞定了吗? 【参考方案1】:

您可以在运行时使用 Expo 清单获取 IP 地址:

import Constants from "expo-constants";
const  manifest  = Constants;

const api = (typeof manifest.packagerOpts === `object`) && manifest.packagerOpts.dev
  ? manifest.debuggerHost.split(`:`).shift().concat(`:3000`)
  : `api.example.com`;

这会将api 常量设置为开发模式下本地开发机器的地址以及您在生产中使用的任何地址。请注意,通过 App Store / Play Store 部署的应用似乎具有 packagerOpts undefined。这就是为什么我们有额外的typeof 条件。在这种情况下,我们假设它是生产版本。

更多关于清单的信息:https://docs.expo.io/versions/latest/workflow/how-expo-works/#expo-development-server

【讨论】:

请注意,这仅在您通过 LAN 提供应用程序时才有效。以下是为隧道启用此功能的功能请求:expo.canny.io/feature-requests/p/tunnels-to-additional-ports this Work for me,需要提一下IP前要加http:// Constants 在最近的版本中已移至 react-native-unimodules 感谢您的评论@borislemke。我做了一个快速的研究,根据docs.expo.io/versions/v36.0.0/sdk/constants expo-constants 仍然是暴露Constants.manifest 的模块。你说这样不行吗?我不再使用 Expo,所以我很难实际测试它。【参考方案2】:
import Constants from "expo-constants";

const  manifest  = Constants;

const uri = `http://$manifest.debuggerHost.split(':').shift():4000`;

【讨论】:

为我节省了宝贵的生命时间【参考方案3】:

您应该将http://localhost:3000/ 地址替换为您计算机的IP 地址。

在 Windows 上,打开提示符并键入 ipconfig,检查网络接口的线路并获取地址 IPV4,应该类似于 192.168.1.20。然后,您可以使用 fetch 和类似 htt://192.168.1.20/routname 的 url 拨打电话。

顺便说一下,您的计算机(服务器)和您的设备必须在同一个本地网络上。 Wifi 和 lan 共享同一个网络。

【讨论】:

救生员。!!!!!!!!!另外,像这样使用端口号。 192.168.1.20:3000/routname【参考方案4】:

要添加到 Tadeusz's answer,在当前版本的 Expo(我现在在 32.0.0)中,您将导入 Constants 而不是 Expo(即使这些常量在文档中被引用为Expo.Constants.manifest),所以它看起来像

import  Constants  from 'expo';
const  manifest  = Constants;

此外,在生成的地址前面加上协议似乎是使一切正常工作的必要条件。

【讨论】:

【参考方案5】:

在我的一生中,我找不到任何我找到的解决方案(包括本页上的所有解决方案)。我花了几天时间尝试。最后,我放弃并通过使用localtunnel 并将我在localhost:8080 上运行的服务暴露给网络来解决整个问题。从我的世博会应用程序调用它时第一次尝试。也许不是最好的长期解决方案,但也不是那么糟糕。我希望这对其他人有帮助!

【讨论】:

【参考方案6】:

试了一些还是不行,最后干脆用ngrok

【讨论】:

【参考方案7】:

另一种简单的方法。首先,您需要在 Mobile HotSpot 上使用 Mobile HotSpot 连接到笔记本电脑。然后检查您分配给您计算机的 ip,并将您使用的 react-native 源中的 api url http://localhost:80/ 地址替换为 http://192.168.5.43:80/。

将端口 80 替换为您的 api 服务器端口号。

确保您在笔记本电脑的防火墙中打开了服务器端口 (80)。

android rest-client https://play.google.com/store/apps/details?id=com.sn.restandroid app 中测试 api (url : http://192.168.5.43:80/api)

【讨论】:

【参考方案8】:

不知道为什么,但这个特定的 IP 地址 与 Android 模拟器有某种关联。我尝试了上述解决方案(机器的私有 IPv4),但也没有用。因此,如果有人在 Android 模拟器中进行开发,那么您可以使用此 IP 地址

http://10.0.2.2

别忘了添加您的 localhost 服务器的 PORT 号码。

【讨论】:

【参考方案9】:

Tad Lispy 的解决方案对我有用。但我的格式有点不同。

我还使用 document 对象添加了对 react-native-web 的支持。

import Constants from "expo-constants";

//const inProduction = manifest.packagerOpts == null;
const inProduction = process.env.NODE_ENV === 'production';
const inExpo = Constants.manifest && Constants.manifest.debuggerHost;
const inBrowser = typeof document !== 'undefined';

export const apiDomain =
    inProduction ? 'mywebsite.com'
  : inExpo ? Constants.manifest.debuggerHost!.split(`:`).shift()
  : inBrowser ? document.location.hostname
  : 'unknown';

console.log('apiDomain:', apiDomain);

const protocol = inProduction ? 'https' : 'http';

const apiUrl = `$protocol//$apiDomain/...`;

【讨论】:

【参考方案10】:

快速简单的解决方案,直接运行!

Localtunnel docs

    全局安装 Localtunnel(需要 NodeJS)以使其在任何地方都可以访问:

npm install -g localtunnel

    在某个本地端口(例如 http://localhost:8000)上启动网络服务器并使用命令行界面请求到本地服务器的隧道:

lt --port 8000

    您将收到一个 URL,例如 https://gqgh.localtunnel.me,只要您的本地 lt 实例保持活动状态,您就可以与任何人共享该 URL。任何请求都将被路由到指定端口的本地服务。

【讨论】:

【参考方案11】:

在我的项目中,我通常通过 config 获取本地开发服务器,因此我调整了 @tiagob 的答案以修补 localhost 地址:

let uri = Config.host;
if (uri.includes('localhost') && manifest.debuggerHost)
  uri = uri.replace(
    'localhost',
    manifest.debuggerHost.split(':').shift()
  );

在生产中,配置不会包含localhost,所以这段代码只会返回未修改的配置变量。

【讨论】:

【参考方案12】:

Divyanshu Singh 详细解释了如何从 Expo 调用本地托管服务器,并提供了一些解决方案:

通过使用 ngrok 或 localtunnel 通过在 0.0.0.0 上运行服务器(这 解决方案对我有用

https://dsinecos.github.io/blog/How-to-call-a-locally-hosted-server-from-expo-app

【讨论】:

【参考方案13】:

【除上述之外】如果使用 Laravel artisan serve,传入你的电脑 ip 作为主机参数:

php artisan serve --host 192.168.0.19 --port 8000

【讨论】:

以上是关于从 Expo App 调用本地托管服务器的主要内容,如果未能解决你的问题,请参考以下文章

从 Expo 调用本地托管的服务器

托管 Parse 服务器时如何在网页中本地调用 Parse?

如何更灵活的处理 CloudKit 从云端同步到本地的 CoreData 托管对象

如何更灵活的处理 CloudKit 从云端同步到本地的 CoreData 托管对象

如何从 Azure Web 应用程序与 IIS 中本地托管的 WCF 服务进行通信?

如何从托管在另一台服务器上的 Web 应用程序调用客户端计算机托管的 Wcf 服务?