You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Expo中为iOS和Android搭建HTTP/TCP服务器?

在Expo中为iOS/Android搭建HTTP/TCP服务器的问题

我希望在Expo项目中为iOS和Android搭建HTTP(至少是TCP)服务器,但导入http模块时出现如下错误:

Unable to resolve module http from /home///screens/LoginModal.tsx: http could not be found within the project or in these directories:
node_modules
../node_modules
1 |

2 | import {createServer} from "http";
...

尝试net等HTTP相关模块,以及Express这类外部库时,也遇到了相同问题。我该如何在Expo中搭建HTTP(或用于实现HTTP的TCP)服务器?我不需要加密连接,该服务器用于OAuth2隐式授权,令牌位于URL的#字符之后。


解决方案

Expo基于React Native,而React Native的JS运行环境不支持Node.js的http、net等核心模块,Express这类依赖Node.js环境的库也无法直接使用。针对你的OAuth2隐式授权场景,推荐以下两种方案:

方案一:用Expo深链接替代本地服务器(推荐)

这是处理OAuth2隐式授权更简洁的方式,无需搭建本地服务器:

  • 配置OAuth2服务提供商,将回调地址设置为你的App深链接(例如myapp://oauth/callback)
  • 在Expo项目的app.json中配置深链接协议:
    {
      "expo": {
        "scheme": "myapp"
      }
    }
    
  • 监听深链接跳转事件,解析URL#后的令牌:
    import * as Linking from 'expo-linking';
    import { useEffect } from 'react';
    
    useEffect(() => {
      // 处理App启动时的深链接
      const handleInitialUrl = async () => {
        const url = await Linking.getInitialURL();
        if (url) parseOAuthToken(url);
      };
    
      // 监听App运行中的深链接跳转
      const subscription = Linking.addEventListener('url', ({ url }) => {
        parseOAuthToken(url);
      });
    
      handleInitialUrl();
      return () => subscription.remove();
    }, []);
    
    const parseOAuthToken = (url: string) => {
      const hashSegment = url.split('#')[1];
      if (!hashSegment) return;
      const params = new URLSearchParams(hashSegment);
      const accessToken = params.get('access_token');
      // 这里处理获取到的令牌
      console.log('获取到的令牌:', accessToken);
    };
    

方案二:使用React Native兼容的本地服务器库

如果必须搭建本地TCP/HTTP服务器,可以使用react-native-tcp-socket(Expo环境需预构建):

  • 安装依赖:
    npx expo install react-native-tcp-socket
    
  • 对于Expo SDK 49+,执行预构建以适配原生模块:
    npx expo prebuild
    
  • 简单TCP服务器示例(可处理HTTP请求):
    import TcpSocket from 'react-native-tcp-socket';
    
    // 创建TCP服务器
    const server = TcpSocket.createServer((socket) => {
      socket.on('data', (rawData) => {
        const request = rawData.toString();
        // 提取请求URL中的#部分(OAuth回调的令牌)
        const urlMatch = request.match(/GET (.+) HTTP\/1\.1/);
        if (urlMatch?.[1]) {
          const callbackUrl = decodeURIComponent(urlMatch[1]);
          const hashSegment = callbackUrl.split('#')[1];
          // 这里可以将令牌通过深链接跳转回App
          const redirectResponse = `HTTP/1.1 302 Found\r\nLocation: myapp://oauth/callback#${hashSegment}\r\n\r\n`;
          socket.write(redirectResponse);
        }
        socket.end();
      });
    
      socket.on('error', (err) => console.error('Socket错误:', err));
      socket.on('close', () => console.log('Socket已关闭'));
    });
    
    // 启动服务器,监听本地3000端口
    server.listen(3000, '0.0.0.0', () => {
      console.log('TCP服务器已启动,监听端口3000');
    });
    
    注意:iOS需确保Info.plist包含网络权限,Android需AndroidManifest.xml添加<uses-permission android:name="android.permission.INTERNET" />,Expo预构建后会自动处理大部分权限配置。

内容的提问来源于stack exchange,提问作者Zombie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 21:57:11