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

如何在react-native-webview请求头中传递JWT令牌访问受保护网页

react-native-webview 传递JWT令牌加载受保护网页失效修复

你写的代码存在两个直接问题,同时受react-native-webview本身的特性限制,按下面步骤排查修复即可:

  • 首先是令牌格式错误:标准Authorization请求头的格式为Bearer <JWT令牌>,Bearer和令牌字符串之间必须有一个半角空格,你当前写法拼接后是BearereyJ0eX...........,服务端无法正确识别令牌前缀,会直接返回未授权。
  • 其次是组件默认行为限制:写在source.headers里的自定义请求头,只会在WebView首次加载主页面时携带,页面内加载的CSS、JS、接口请求、路由跳转等后续请求,都不会自动带上这个头,只要受保护站点对这些子资源做了权限校验,就会出现加载失败、白屏、跳登录页的问题。

基础修复(仅需校验主页面权限场景)

如果你的站点只对首屏页面请求做JWT校验,补上Bearer后面的空格即可正常使用:

<WebView
  source={{
    uri: '替换为你的目标网站地址',
    headers: {
      Authorization: 'Bearer eyJ0eX...........', // 注意Bearer后保留半角空格
    },
  }}
/>

全场景修复(子资源/跳转都需要携带令牌场景)

如果改完格式还是加载失败,就需要拦截WebView内的所有请求,手动给所有同域请求注入JWT头,注意安卓端需要将react-native-webview版本升级到11.0.0以上才支持完整的拦截能力:

import React, { useRef } from 'react';
import { Platform } from 'react-native';
import { WebView } from 'react-native-webview';

const ProtectedWebView = () => {
  const webViewRef = useRef(null);
  // 实际使用时替换为动态获取的JWT令牌,不要硬编码
  const JWT_TOKEN = 'eyJ0eX...........';
  const TARGET_ORIGIN = '替换为你的目标网站根地址';

  const handleRequestIntercept = (request) => {
    // 只拦截目标站点下的请求,避免影响第三方资源加载
    if (!request.url.startsWith(TARGET_ORIGIN)) return true;

    // 安卓端通过注入JS重写fetch和XMLHttpRequest,自动给所有请求加头
    if (Platform.OS === 'android') {
      const injectAuthScript = `
        // 重写fetch
        const originFetch = window.fetch;
        window.fetch = (resource, init = {}) => {
          init.headers = {
            ...init.headers,
            Authorization: 'Bearer ${JWT_TOKEN}'
          };
          return originFetch(resource, init);
        };

        // 重写XMLHttpRequest
        const originXhrOpen = XMLHttpRequest.prototype.open;
        const originXhrSend = XMLHttpRequest.prototype.send;
        XMLHttpRequest.prototype.open = function(method, url) {
          this._reqUrl = url;
          return originXhrOpen.apply(this, arguments);
        };
        XMLHttpRequest.prototype.send = function(body) {
          if (this._reqUrl?.startsWith('${TARGET_ORIGIN}')) {
            this.setRequestHeader('Authorization', 'Bearer ${JWT_TOKEN}');
          }
          return originXhrSend.call(this, body);
        };
        true;
      `;
      webViewRef.current?.injectJavaScript(injectAuthScript);
      return true;
    }

    // iOS端直接在拦截回调里返回带自定义头的请求
    return {
      ...request,
      headers: {
        ...request.headers,
        Authorization: `Bearer ${JWT_TOKEN}`
      }
    };
  };

  return (
    <WebView
      ref={webViewRef}
      source={{
        uri: TARGET_ORIGIN,
        headers: {
          Authorization: `Bearer ${JWT_TOKEN}`
        }
      }}
      onShouldStartLoadWithRequest={handleRequestIntercept}
      sharedCookiesEnabled={true}
      javaScriptEnabled={true}
    />
  );
};

export default ProtectedWebView;

额外注意事项

  • 如果目标站点开启了严格CORS校验,前端注入请求头的方式可能被跨域策略拦截,这种情况需要服务端配合配置跨域规则,或者由服务端做代理转发。
  • 部分深度定制的安卓ROM会篡改WebView默认请求头,如果遇到个别机型始终带不上头,可以让服务端兼容读取自定义头比如X-Authorization里的令牌,前端把令牌同时放到这个自定义头里做兼容。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 01:01:06