React前端无服务端代码调用远程POST API的实现方法
问题描述
我正在尝试在React.js项目中通过fetch/axios的POST API访问远程URL,以下是我编写的React代码:
const requestOptions = { method: 'POST', crossDomain: true, mode: 'cors', // no-cors, *cors, same-origin credentials: 'same-origin', // include, *same-origin, omit headers:{ 'Content-Type': 'application/x-www-form-urlencoded', "Access-Control-Allow-Origin": "*", 'Access-Control-Allow-Headers': 'Content-Type', 'Access-Control-Allow-Methods': 'GET,POST,OPTIONS,DELETE,PUT' }, redirect: 'follow', // manual, *follow, error referrerPolicy: 'no-referrer', body:new URLSearchParams({ 'store_id':'storeid', 'store_passwd':'storepass', 'total_amount':100, 'currency':'BDT', 'tran_id':'NF04', 'success_url':"https://tigrow.herokuapp.com", 'fail_url':"https://tigrow.herokuapp.com", 'cancel_url':"https://tigrow.herokuapp.com", 'cus_name':"nizam", 'cus_email':"test@test.com", 'cus_add1':"customer address", 'cus_add2':"customer address", 'cus_city':"Dhaka", 'cus_state':"Dhaka2", 'cus_postcode':"Dhaka", 'cus_country':"Bangladesh", 'cus_phone':"01700000000", 'cus_fax':"01700000000", 'ship_name':"Sha", 'ship_add1':"dhaka", 'ship_add2':"dhaka1", 'ship_city':"Dhaka1", 'ship_state':"Dhaka2", 'ship_postcode':"1000", 'ship_country':"Bangladesh", 'multi_card_name':"mastercard,visacard,amexcard", 'value_a':"ref001_A", 'value_b':"ref002_B", 'value_c':"ref003_C", 'value_d':"ref004_D", 'shipping_method':"No", 'product_name':"Test", 'product_category':"Test Category", 'product_profile':"general" }) }; fetch(url, requestOptions) .then(response =>console.log(response)) .then(data => console.log(data));
我希望仅通过React.js实现远程API的数据获取,不编写任何服务端代码,当前请求的Content-Type为application/x-www-form-urlencoded,请问仅使用React.js如何解决该问题?
问题根源
你现在的代码有两个核心错误,也是跨域请求失败的主要原因:
- 你把
Access-Control-Allow-*系列的CORS响应头写在了请求头里。这类头是服务端返回响应时配置的,前端发请求时加这些头完全无效,反而可能触发预检请求拦截。 - CORS限制是浏览器的同源安全策略,纯前端代码没有权限绕过这个限制,除非目标接口服务端本身配置了允许你的前端源访问,或者通过代理转发请求绕开浏览器同源校验。
纯前端可行的解决方案
所有方案都不需要你自己编写后端代码,完全在React侧或项目配置层即可实现:
- 先修正无效的请求配置
首先把headers里所有Access-Control-开头的字段全部删掉,这些字段前端配置没有任何作用,同时调整credentials配置避免不必要的跨域拦截,修正后的基础请求配置如下:const requestOptions = { method: 'POST', mode: 'cors', // 目标接口不需要cookie鉴权时,credentials设为omit,避免跨域cookie拦截 credentials: 'omit', headers:{ 'Content-Type': 'application/x-www-form-urlencoded' }, redirect: 'follow', referrerPolicy: 'no-referrer', body:new URLSearchParams({ // 保留你原有的所有业务参数即可 'store_id':'storeid', 'store_passwd':'storepass', 'total_amount':100, 'currency':'BDT', 'tran_id':'NF04', 'success_url':"https://tigrow.herokuapp.com", 'fail_url':"https://tigrow.herokuapp.com", 'cancel_url':"https://tigrow.herokuapp.com", 'cus_name':"nizam", 'cus_email':"test@test.com", 'cus_add1':"customer address", 'cus_add2':"customer address", 'cus_city':"Dhaka", 'cus_state':"Dhaka2", 'cus_postcode':"Dhaka", 'cus_country':"Bangladesh", 'cus_phone':"01700000000", 'cus_fax':"01700000000", 'ship_name':"Sha", 'ship_add1':"dhaka", 'ship_add2':"dhaka1", 'ship_city':"Dhaka1", 'ship_state':"Dhaka2", 'ship_postcode':"1000", 'ship_country':"Bangladesh", 'multi_card_name':"mastercard,visacard,amexcard", 'value_a':"ref001_A", 'value_b':"ref002_B", 'value_c':"ref003_C", 'value_d':"ref004_D", 'shipping_method':"No", 'product_name':"Test", 'product_category':"Test Category", 'product_profile':"general" }) }; - 本地开发环境用框架自带代理解决跨域
如果你是用Create React App搭建的项目,不需要自己写后端代码,直接在项目根目录的package.json里加一行代理配置即可:
比如你要请求的接口地址是"proxy": "你要请求的远程接口的域名根路径"https://example.com/pay/api,那proxy就填"https://example.com",之后前端发请求时url直接写路径部分/pay/api即可,开发环境会自动把请求转发到目标域名,不会触发跨域拦截。注意:这个代理仅在本地开发环境生效,线上部署时可以直接用托管平台自带的转发规则(比如静态托管平台的重定向/代理配置),同样不需要自己写服务端代码。
- 不要尝试无效的绕过方案
不要把请求mode改成no-cors,这个模式下你拿到的响应是不透明类型,根本读不到返回的业务内容,没有实际意义;JSONP方案仅支持GET请求,不适配你当前的POST请求场景。
如果目标接口本身没有配置CORS允许跨域,你也不想用代理转发,那纯前端不可能直接拿到接口响应数据,这是浏览器的底层安全限制,和React、fetch的写法无关。
内容的提问来源于stack exchange,提问作者Shahanaz Sultana
相关产品推荐
相关产品推荐

