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

如何在Dart服务端使用shelf获取用户IP地址?

在Shelf框架中获取客户端IP地址

问题分析

你尝试的代码返回null,通常是因为无反向代理场景下x-forwarded-for请求头不存在,且连接信息的获取或类型处理存在疏漏。以下是修正后的可行方案:

解决方案

修改路由处理函数,通过以下方式正确获取客户端IP:

import 'dart:io';
import 'package:shelf/shelf.dart';
import 'package:shelf/shelf_io.dart' as shelf_io;
import 'package:shelf_router/shelf_router.dart' as shelf_router;
import 'package:shelf_static/shelf_static.dart' as shelf_static;

Future main(List<String> arguments) async {
  final cascade = Cascade().add(_staticHandler).add(_router);
  final server = await shelf_io.serve(logRequests().addHandler(cascade.handler), InternetAddress.anyIPv4, 8080);
  print('Server running on ${server.address.address}:${server.port}');
}

final _staticHandler = shelf_static.createStaticHandler('public', defaultDocument: 'index.html');
final _router = shelf_router.Router()
  ..get('/get', (Request request) async {
    String? clientIp;
    
    // 1. 反向代理场景(如Nginx):优先读取X-Forwarded-For头
    final forwardedFor = request.headers['x-forwarded-for'];
    if (forwardedFor != null && forwardedFor.isNotEmpty) {
      // 该头可能包含多个IP,取第一个为原始客户端IP
      clientIp = forwardedFor.split(',').first.trim();
    } 
    // 2. 直接连接场景:从框架注入的连接信息中获取IP
    else {
      final connectionInfo = request.context['shelf.io.connection'] as HttpConnectionInfo?;
      clientIp = connectionInfo?.remoteAddress.address;
    }

    return Response(HttpStatus.ok, body: 'Your IP address is: $clientIp');
  })
  ..post('/post', (Request request) async {
    String? clientIp;
    final forwardedFor = request.headers['x-forwarded-for'];
    if (forwardedFor != null && forwardedFor.isNotEmpty) {
      clientIp = forwardedFor.split(',').first.trim();
    } else {
      final connectionInfo = request.context['shelf.io.connection'] as HttpConnectionInfo?;
      clientIp = connectionInfo?.remoteAddress.address;
    }
    return Response(HttpStatus.ok, body: 'Post request from IP: $clientIp');
  })
  ..all('/<ignored|.*>', (Request request) {
    return Response(HttpStatus.notFound);
  });

关键说明

  • 反向代理适配:若服务部署在Nginx等反向代理后,需确保代理服务器配置了X-Forwarded-For头,将客户端真实IP传递给Shelf服务。
  • 直接连接逻辑:request.context['shelf.io.connection']是Shelf框架自动注入的连接信息对象,包含直接连接的客户端IP,类型转换时需注意空安全判断。
  • 异常规避:添加了对x-forwarded-for非空的校验,避免空字符串分割导致的运行时异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 07:53:23