如何从外部的Node/Express服务器重定向页面?
如何从外部的Node/Express服务器重定向页面?
我有一个React/Node/Express的Web应用正在运行,有两个独立的服务器。React运行在localhost:8080
,代理API请求到运行在localhost:3000
的node服务器上。这将是我在生产环境中的设置,所以如果可能的话,我希望保持这个结构不变。
我遇到的问题是,我的API的一部分需要将用户重定向到一个页面,从Spotify API中获取一个令牌,然后在成功验证后重定向回我的正确页面。
API调用代理是这样做的:
const axios = require('axios'); const axiosInstance = axios.create({ baseURL: process.env.NODE === 'production' ? '' : 'http://localhost:3000' }); module.exports = axiosInstance;
到目前为止,这个方法很好用,因为我可以完全分离我的React和Node服务器。
正如我上面提到的,我需要通过后端的API调用将我的React前端重定向到一个不同的页面(Spotify认证)来验证用户,然后在用户允许或拒绝访问他们的Spotify账户后,Spotify会将用户重定向回我的网站。
在我的前端 - localhost:8080
,用户点击一个按钮,调用这个函数。
authenticate = () => { axios.get('/login') .then(data => console.log(data)); }
这将调用localhost:3000
上的这个端点。
router.get('/', (req, res) => { let scopes = 'user-read-private user-read-email'; let client = process.env.SPOTIFY_CLIENT; let redirect = 'http://localhost:3000/login/redirect'; res.redirect(`https://accounts.spotify.com/authorize?response_type=code' &client_id=${client}${scopes ? `&scope=${encodeURIComponent(scopes)}` : ''} &redirect_uri=${encodeURIComponent(redirect)}&state=${state}`); });
当我在前端点击登录按钮时,我得到这个响应,我相信这是来自Spotify的,因为我可以成功地对我的API中的其他端点进行跨域请求。
Failed to load... No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.
然而,当我手动导航到localhost:3000/login
时,重定向起作用,我被发送到Spotify认证页面。
此外,我尝试重定向我的前端到任何URL,但它不起作用。
所以我的问题是,如何在不提供静态前端内容的服务器上通过API调用将我的前端重定向?
问题的原因是,axios.get('/login')
是一个向服务器发送的AJAX请求,服务器告诉AJAX请求要重定向到Spotify,但是Spotify没有注册你的前端服务器,所以你得到了CORS错误,因为你的请求是在前端服务器URL上发起的。
你的AJAX请求会遵循给出的重定向,而不是尝试在http://localhost:3000
上加载你的浏览器,然后再重定向到Spotify的授权页面。
现在,你可以这样做:
authenticate = () => { window.location.href = "http://localhost:3000" }
这将使你的前端应用程序访问API服务器的URL,并立即跟随重定向到Spotify,然后你可以进行授权并被重定向回你的API服务器,然后API服务器可以重定向回你的前端应用程序。
实际上,这有点过分了,因为假设你的React应用程序和Node应用程序在开发之外看起来像是在同一个域上运行,因为你使用的是相对URL。如果你使用的是create-react-app
,你应该按照他们的说明通过这个或者通过这个手动配置代理。
简而言之,你需要调整代理的配置方式,或者改为直接访问/login
而不是进行AJAX请求。
这个解决方法有效。我曾考虑过在package.json
中指定代理,但决定尝试这个方法(我没有使用CRA)。我确实理解你的观点,这有点过分。我主要设置这个项目是因为我想要使用任何语言编写我的后端,并进行一些关于查询不同后端的研究,这就是我找到有关设置axios基本URL的方法。