我有一个 React/Node/Express Web 应用程序,并在两个单独的服务器上运行。 React 正在 localhost:8080
上运行,并将 API 请求代理到在 localhost:3000
上运行的 Node 服务器。这将是我的生产设置,所以如果可能的话,我想保持这个结构完整。
我遇到的问题是我的 API 需要将用户重定向到一个页面以从 Spotify API 获取 token ,然后在身份验证成功后重定向回正确的页面。
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 中的其他端点发出跨源请求。
无法加载...请求的资源上不存在“Access-Control-Allow-Origin” header 。因此,不允许访问源“null”。
但是,当我手动导航到 localhost:3000/login
时,重定向会起作用,并且我会被发送到 Spotify 身份验证页面。
此外,我测试了尝试将我的前端重定向到任何网址,但它不起作用。
所以我的问题是,如何通过来自不提供静态前端内容的服务器的 API 调用来重定向我的前端?
最佳答案
这不起作用的原因是您的 axios.get('/login')
是对您的服务器的 AJAX 请求,然后您的服务器会告诉 AJAX 请求重定向到 Spotify ,但 Spotify 没有注册您的前端服务器,因此您会收到 CORS 错误,因为您的请求是在前端服务器 URL 上发起的。
Your AJAX request is following that redirect that was given ,而不是尝试在 http://localhost:3000
上加载浏览器,然后将其重定向到 Spotify 授权页面。
现在,而不是这样做:
authenticate = () => {
axios.get('/login')
.then(data => console.log(data));
}
你可以这样做:
authenticate = () => {
window.location.href = "http://localhost:3000"
}
这将引导您的前端应用程序访问 API 服务器的 URL,并立即按照重定向到 Spotify,然后您可以授权并重定向回您的 API 服务器,然后可以重定向回您的前端应用程序。
说实话,这有点矫枉过正,因为考虑到您正在使用的相对 URL,您的 React 应用程序和 Node 应用程序看起来像是在开发之外的同一域上运行。如果您使用 create-react-app
,您应该按照他们的说明通过 this 配置您的代理。或通过this手动.
tl;dr,您需要修改代理的配置方式或,从执行 AJAX 请求更改为实际直接访问 /login
(不执行 AJAX请求)。
关于node.js - 如何从外部 Node/Express 服务器重定向页面,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49483452/