如何从浏览器控制台获取 localhost 资源而不出现违反内容安全策略的错误?
How can I fetch a localhost resource from the browser console and not get the Content Security Policy violation error?
我有最简单的本地 http 服务器,它连接到本地主机提供单个文件。我可以很好地从浏览器导航到资源,但我需要能够从浏览器控制台使用 fetch
网络 api 获取资源,但这不起作用 除非控制台来自完全相同的来源.
请注意:
资源已上线:
C:\> (Invoke-WebRequest http://localhost:49152/C:/temp/events/62.0.0.32712-0515-834-4.build.Main_events.json).StatusCode
200
C:\>
控制台同源时:
否则:
我知道我可以忽略第一个错误 - 提到 http://127.0.0.1:9001 的错误。所以我的问题是第二个错误:
Refused to connect to 'http://localhost:49152/C:/temp/events/62.0.0.32712-0515-834-4.build.Main_events.json' because it violates the document's Content Security Policy.
到目前为止我还没有弄清楚如何修复它。这似乎是经典的 CORS 问题,但是当 运行 fetch
时,浏览器不会发出任何预检 OPTIONS 请求。我知道这一点,因为我是 运行 Fiddler。它显示来自同一来源的 GET
请求,但绝对没有来自其他来源的请求。
我尝试使用的原始 fetch
代码是这样的:
const request = fetch(url)
.then(response => response.blob())
.then(blob => {
globals.dispatch(Actions.openTraceFromFile({
file: new File([blob], fileName),
}));
})
.catch(e => alert(`Could not load local trace ${e}`));
它来自 https://www.ui.perfetto.dev/,我试图以非交互方式加载我的跟踪文件。
(此问题与 and 有关)
我尝试 运行 chrome 使用 --disable-web-security
标志,这应该禁用 CORS 验证(据我对这个标志的最佳理解)。无果。
我能做些什么来让它发挥作用吗?
网络服务器源代码:
function NavigateToFile(
[Parameter(Mandatory)][ValidateScript({ Test-Path $_ -PathType Leaf })]$FilePath,
[scriptblock]$Action
)
{
$port = Get-OpenTcpPort
$http = [Net.HttpListener]::new()
$http.Prefixes.Add("http://localhost:$Port/")
$http.Start()
$FilePath = (Get-Item $FilePath).FullName.Replace('\', '/')
$ExpectedUrl = "$($http.Prefixes)$FilePath"
$ExpectedUrl | ForEach-Object $Action
try
{
$run = $true
while ($http.IsListening -and $run)
{
$context = $http.GetContext()
Write-Host "$($context.Request.HttpMethod) $($context.Request.Url)"
if ($context.Request.HttpMethod -eq 'GET')
{
if ($context.Request.Url -eq $ExpectedUrl)
{
$buffer = [IO.File]::ReadAllBytes($FilePath)
}
else
{
$buffer = [Text.Encoding]::UTF8.GetBytes("Terminated")
$run = $false
}
$context.Response.ContentLength64 = $buffer.Length
$context.Response.OutputStream.Write($buffer, 0, $buffer.Length)
$context.Response.OutputStream.Close()
}
}
}
finally
{
$http.Close();
}
}
这不是 CORS,它是内容安全策略,在此处定义:
https://github.com/google/perfetto/blob/master/ui/src/frontend/index.ts#L127
它仅支持从 localhost:9001 获取以减少攻击面。
如果您让网络服务器侦听端口 9001 而不是随机端口,错误应该会消失。
我有最简单的本地 http 服务器,它连接到本地主机提供单个文件。我可以很好地从浏览器导航到资源,但我需要能够从浏览器控制台使用 fetch
网络 api 获取资源,但这不起作用 除非控制台来自完全相同的来源.
请注意:
资源已上线:
C:\> (Invoke-WebRequest http://localhost:49152/C:/temp/events/62.0.0.32712-0515-834-4.build.Main_events.json).StatusCode
200
C:\>
控制台同源时:
否则:
我知道我可以忽略第一个错误 - 提到 http://127.0.0.1:9001 的错误。所以我的问题是第二个错误:
Refused to connect to 'http://localhost:49152/C:/temp/events/62.0.0.32712-0515-834-4.build.Main_events.json' because it violates the document's Content Security Policy.
到目前为止我还没有弄清楚如何修复它。这似乎是经典的 CORS 问题,但是当 运行 fetch
时,浏览器不会发出任何预检 OPTIONS 请求。我知道这一点,因为我是 运行 Fiddler。它显示来自同一来源的 GET
请求,但绝对没有来自其他来源的请求。
我尝试使用的原始 fetch
代码是这样的:
const request = fetch(url)
.then(response => response.blob())
.then(blob => {
globals.dispatch(Actions.openTraceFromFile({
file: new File([blob], fileName),
}));
})
.catch(e => alert(`Could not load local trace ${e}`));
它来自 https://www.ui.perfetto.dev/,我试图以非交互方式加载我的跟踪文件。
(此问题与
我尝试 运行 chrome 使用 --disable-web-security
标志,这应该禁用 CORS 验证(据我对这个标志的最佳理解)。无果。
我能做些什么来让它发挥作用吗?
网络服务器源代码:
function NavigateToFile(
[Parameter(Mandatory)][ValidateScript({ Test-Path $_ -PathType Leaf })]$FilePath,
[scriptblock]$Action
)
{
$port = Get-OpenTcpPort
$http = [Net.HttpListener]::new()
$http.Prefixes.Add("http://localhost:$Port/")
$http.Start()
$FilePath = (Get-Item $FilePath).FullName.Replace('\', '/')
$ExpectedUrl = "$($http.Prefixes)$FilePath"
$ExpectedUrl | ForEach-Object $Action
try
{
$run = $true
while ($http.IsListening -and $run)
{
$context = $http.GetContext()
Write-Host "$($context.Request.HttpMethod) $($context.Request.Url)"
if ($context.Request.HttpMethod -eq 'GET')
{
if ($context.Request.Url -eq $ExpectedUrl)
{
$buffer = [IO.File]::ReadAllBytes($FilePath)
}
else
{
$buffer = [Text.Encoding]::UTF8.GetBytes("Terminated")
$run = $false
}
$context.Response.ContentLength64 = $buffer.Length
$context.Response.OutputStream.Write($buffer, 0, $buffer.Length)
$context.Response.OutputStream.Close()
}
}
}
finally
{
$http.Close();
}
}
这不是 CORS,它是内容安全策略,在此处定义:
https://github.com/google/perfetto/blob/master/ui/src/frontend/index.ts#L127
它仅支持从 localhost:9001 获取以减少攻击面。
如果您让网络服务器侦听端口 9001 而不是随机端口,错误应该会消失。