我试图向用户隐藏一个URL,告诉应用程序应该使用哪个端点。
在nuxt中,我有两个插件。
[
"~/endpoint.server.js",
"~/api.js",
]
在 endpoint.server.js
,我为所有后续的请求获取一个端点,以运行在 如果 我的应用程序在生产中。我不想让这个URL(下面的private.com)公开,因此只在服务器上运行它。
import axios from 'axios';
export default async function ({ $axios, redirect, app }, inject) {
// Set staging
let staging = !!app.$env.STAGING;
app.$staging = staging;
inject('staging', staging);
if(app.$staging){
inject('baseURL', "https://staging-data.com");
}else{
// console.log("Setting custom endpoint");
let { data } = await axios.get("http://private.com");
inject('baseURL', data.endpoint);
}
}
请注意我是如何 inject
的$baseURL。然后,在api.js里面我有以下内容。
export default async function ({ $axios, redirect, app }, inject) {
// Create a custom axios instance
const api = $axios.create();
// Set the base URL
api.setBaseURL(app.$baseURL);
// Inject to context as $api
inject('api', api);
}
在我所有的组件中,我使用了这个特殊的axios实例。
async asyncData({ $axios, route, app }) {
const page = await app.$api.$get( "/" );
return { page }
},
在第一次页面加载时,这一切都很好。然而,在随后的页面加载中, $api
baseURL被设置为 localhost
在客户端。
我敢肯定,在 endpoint.server.js
我正确使用了 combined inject
– https:/nuxtjs.orgguideplugins#combined-inject。 - 为什么我的 axios 实例不能使用 baseURL
?
你的插件 endpoint.server.js
只在服务器端运行。也就是说,Axios只在服务器端知道这些基础url端点。
当插件 api.js
在客户端运行。app.$baseURL
是 undefined
. 因为: $baseURL
注入只发生在服务器端,通过 endpoint.server.js
. 你可以通过进入你的浏览器控制台来验证这一点,并检查是否有以下情况 $nuxt.$baseURL
被定义为。这绝对是 undefined
.
它在第一次加载时工作的原因是,几乎所有的事情都发生在服务器端。所以浏览器上没有Axios的调用。但是一旦你开始在浏览器上导航,你的应用程序的SPA版本(客户端)就开始执行,而客户端Axios不知道你的baseURLs。这就是为什么它把 localhost
作为你的基本url,然后事情就会出错。
如果你想从客户端隐藏API端点,那么你应该采取的方法可能是服务器中间件。这基本上是你的API代理。你调用 服务器中间件 从Axios(例如apiwhatever)和服务器中间件与你的隐藏API端点对话。
这应该可以得到你想要的结果。
一个更好的选择是使用一个 斧式代理 其目标值是通过ENV变量设置的。在你的nuxt配置中,你会有这样的东西。
module.exports = {
axios: {
proxy: true,
prefix: '/api/'
},
proxy: {
'/api/': {
target: process.env.API_URL,
pathRewrite: { '^/api/': '' }
}
},
// etc.
}
然后,请求 /api/foo
被转发到 http://private.com/foo
如果你 API_URL
环境变量是 http://private.com/
.
然而,这并不意味着这个URL对用户是隐藏的,因为你的前端代码仍然需要知道如何进行API请求。这就是为什么你还需要使用类似于 JSON网络令牌 来确保API请求是由一个有效的用户完成的。
或者,你可以在Nuxt旁边运行一个轻量级服务器(比如Express),自己转发API请求,这样用户就看不到API的实际URL了。不过这对于静态网站来说是行不通的,因为你需要运行那个服务器端的代码。