我正在构建电子应用程序,需要在API提供程序未启用CORS的情况下调用API。通常建议的解决方案是使用反向代理,当通过使用node和cors进行本地运行时,这样做很简单:
let port = (process.argv.length > 2) ? parseInt (process.argv[2]) : 8080;
require ('cors-anywhere').createServer ().listen (port, 'localhost');
然后可以将该应用程序配置为通过localhost:8080上的反向代理来代理所有请求。
所以,我的问题是:
是否可以在电子应用程序中的任何位置使用节点和cors来创建反向代理?我不想强迫应用程序调用远程服务器。
在Electron应用程序中,有没有更好或更标准的方法?我假设我不是第一个遇到CORS问题的人。 :)
答案 0 :(得分:1)
今天刚发生此问题API calls with axios inside a React app bundled in Electron is returning 400
据我所见,Electron调用就像是对API URL的常规调用,这意味着它们不受CORS的影响。
现在,当您使用CORS代理包装呼叫并进行常规调用时,由于它不是CORS呼叫,它应该会出现400错误的错误。 该线程解释了为什么cors-anywhere会这样响应=> https://github.com/Rob--W/cors-anywhere/issues/39
实际上,在构建Electron之前,我已经从应用程序中删除了我的CORS代理。由于我正在浏览器中进行测试,因此我仍然需要CORS代理进行开发。
希望这会有所帮助。
答案 1 :(得分:1)
在我的应用程序中,仅删除请求中的Origin
标头(将其设置为null)是不够的。我传递请求的服务器始终在响应中提供Access-Control-Allow-Origin
头,无论请求中是否存在Origin
头。因此,Chrome的嵌入式实例不喜欢ACAO
标头与对来源的理解不匹配。
相反,我不得不更改请求上的Origin
标头,然后将其恢复到响应上的Access-Control-Allow-Origin
标头上。
app.on('ready', () => {
// Modify the origin for all requests to the following urls.
const filter = {
urls: ['http://example.com/*']
};
session.defaultSession.webRequest.onBeforeSendHeaders(
filter,
(details, callback) => {
console.log(details);
details.requestHeaders['Origin'] = 'http://example.com';
callback({ requestHeaders: details.requestHeaders });
}
);
session.defaultSession.webRequest.onHeadersReceived(
filter,
(details, callback) => {
console.log(details);
details.responseHeaders['Access-Control-Allow-Origin'] = [
'capacitor-electron://-'
];
callback({ responseHeaders: details.responseHeaders });
}
);
myCapacitorApp.init();
});
答案 2 :(得分:1)
您可以让主进程,即运行 Electron 的 NodeJS 服务器发送请求。这避免了 CORS,因为这是一个服务器到服务器的请求。您可以使用 IPC 从前端(渲染进程)向主进程发送事件。在主流程中,您可以listen到这个事件,发送 HTTP 请求,并向前端返回一个承诺。
在 main.js(创建 Electron 窗口的脚本)中:
import { app, protocol, BrowserWindow, ipcMain } from ‘electron’
import axios from 'axios'
ipcMain.handle('auth', async (event, ...args) => {
console.log('main: auth', event, args) const result = await axios.post(
'https://api.com/auth',
{
username: args[0].username,
password: args[0].password,
auth_type: args[1],
},
) console.log('main: auth result', result)
console.log('main: auth result.data', result.data) return result.data
})
在您的前端 JS 中:
import { ipcRenderer } from 'electron'
sendAuthRequestUsingIpc() {
return ipcRenderer.invoke('auth',
{
username: AuthService.username,
password: AuthService.password,
},
'password',
).then((data) => {
AuthService.AUTH_TOKEN = data['access_token']
return true
}).catch((resp) => console.warn(resp))
}
我写了一篇更深入的文章here。
答案 3 :(得分:1)
如果您在 localhost 中运行 Web 应用程序,请尝试此操作
const filter = {
urls: ['http://example.com/*'] // Remote API URS for which you are getting CORS error
}
browserWindow.webContents.session.webRequest.onBeforeSendHeaders(
filter,
(details, callback) => {
details.requestHeaders.Origin = `http://example.com/*`
callback({ requestHeaders: details.requestHeaders })
}
)
browserWindow.webContents.session.webRequest.onHeadersReceived(
filter,
(details, callback) => {
details.responseHeaders['access-control-allow-origin'] = [
'capacitor-electron://-',
'http://localhost:3000' // URL your local electron app hosted
]
callback({ responseHeaders: details.responseHeaders })
}
)
答案 4 :(得分:0)
在发送请求之前先覆盖标头
const filter = {
urls: ['*://*.google.com/*']
};
const session = electron.remote.session
session.defaultSession.webRequest.onBeforeSendHeaders(filter, (details, callback) => {
details.requestHeaders['Origin'] = null;
details.headers['Origin'] = null;
callback({ requestHeaders: details.requestHeaders })
});
将这些代码放入渲染器过程
答案 5 :(得分:-1)
您是否尝试过使用fetch()
在此处检查如何使用提取进行无要求的请求
https://developers.google.com/web/updates/2015/03/introduction-to-fetch?hl=en