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

Clojure服务与React Native通信出现Error 403问题如何解决?

解决Clojure服务与React Native Axios通信的403错误问题

问题背景

我在localhost:3000运行一个Clojure服务,React Native客户端用Axios调用/api/invest接口时收到403错误,而且服务端featured/invest函数里的日志完全没输出,说明请求根本没到达业务处理逻辑。

错误原因分析

  1. CSRF保护拦截请求:服务端路由配置里给根路径""加了middleware/wrap-csrf中间件,这个中间件会验证请求中的CSRF token。但React Native是原生APP,不是浏览器环境,没法自动获取并携带Cookie里的CSRF token,所以请求直接被拦截返回403。
  2. 路由请求方法不匹配:客户端用axios.post发送POST请求,但服务端路由里的/api/invest没有明确指定请求方法,Reitit默认会匹配GET请求——不过这里因为CSRF先拦截了,所以先出现403错误。
  3. CORS预检请求未处理:React Native跨域请求会先发送OPTIONS预检请求,当前服务端只有在invest函数返回时才带CORS头,但OPTIONS请求根本没走到这个函数,预检失败也会间接导致请求异常。

具体解决方案

1. 给API路由禁用CSRF保护

API接口通常使用Token认证,不需要CSRF保护,我们可以把/api路径的中间件单独配置,去掉CSRF:

修改服务端路由代码:

(defn home-routes []
  ["" {:middleware [middleware/wrap-csrf middleware/wrap-formats]}
   ["/" {:get home-page}]
   ; 单独给/api配置中间件,移除wrap-csrf
   ["/api" {:middleware [middleware/wrap-formats]}
    ["/about" {:get about-page}]
    ["/featured" {:get featured/get-featured}] ; 明确请求方法
    ["/invest" {:post featured/invest}] ; 明确指定POST方法,匹配客户端请求
    ]
   ])

2. 全局处理CORS跨域

使用ring-cors库统一处理跨域请求,包括OPTIONS预检请求:

  • 首先在project.clj里添加依赖:
    [ring-cors "0.1.13"]
    
  • 然后在humboiserver.middleware里添加CORS中间件:
    (ns humboiserver.middleware
      (:require [ring.middleware.cors :refer [wrap-cors]]
                ; 保留其他原有依赖
                ))
    
    ; 新增CORS中间件配置(开发环境宽松设置,生产环境需限制来源)
    (defn wrap-cors [handler]
      (wrap-cors handler
                 :access-control-allow-origin [#".*"]
                 :access-control-allow-methods [:get :post :put :delete :options]
                 :access-control-allow-headers ["Content-Type"]))
    
  • 最后在服务端入口(比如handler.clj)把wrap-cors添加到中间件链最前面,确保所有请求都经过CORS处理。

3. 修复客户端Axios调用的问题

  • 给URL加上http://前缀,Axios需要完整的HTTP地址;
  • 因为是async函数,要加await获取实际响应对象,不然res是Promise,无法直接取res.data:

修改客户端代码:

export const invest = (itemid, amount) => async dispatch => { 
  console.log("investing in actions") 
  const domain = 'http://localhost:3000' 
  const res = await axios.post(domain + '/api/invest', {itemid: itemid, amount: amount}); 
  console.log("response is", res) 
  dispatch({ type: INVESTED, payload: res.data}); 
}

验证修改

做完以上修改后,重启Clojure服务,再测试React Native客户端的调用:

  • 服务端invest函数里的prn "invested"应该能正常打印日志;
  • 客户端应该能收到200响应,不再返回403错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 08:20:21