在Javascript中使用fetch的相对路径

21 javascript path relative-path fetch-api

我对今天Javascript中相对路径的体验感到惊讶.我把情况归结为以下情况:

假设您有一个目录结构,如:

app/
   | 
   +--app.html
   +--js/
        |
        +--app.js
        +--data.json
Run Code Online (Sandbox Code Playgroud)

app.html所做的一切都是运行js/app.js

<!DOCTYPE html>
<title>app.html</title>
<body>
<script src=js/app.js></script>
</body>
Run Code Online (Sandbox Code Playgroud)

app.js加载JSON文件并将其粘贴在以下的开头body:

// js/app.js
fetch('js/data.json') // <-- this path surprises me
  .then(response => response.json())
  .then(data => app.data = data)
Run Code Online (Sandbox Code Playgroud)

数据是有效的JSON,只是一个字符串:

"Hello World"
Run Code Online (Sandbox Code Playgroud)

这是一个非常小的用法fetch,但我很惊讶我传递给的URL fetch必须是相对app.html而不是相对的app.js.我希望这条道路的工作,因为data.jsonapp.js在同一个目录(js/):

fetch('data.json') // nope
Run Code Online (Sandbox Code Playgroud)

有没有解释为什么会这样?

小智 26

当您说fetch('data.json')您有效请求时,http://yourdomain.com/data.json因为它是相对于您正在发出请求的页面.您应该使用正斜杠,这将指示路径相对于域根:fetch('/js/data.json').或完全符合您的域名fetch('http://yourdomain.com/js/data.json').

  • 这只是域还是真正的来源,即 FQDN 以及正在使用的 HTTP 端口,例如 http://yourdomain.com:8080/data.json ? (3认同)
  • Chrome 中的行为是它总是被认为是相对于根的,即使这是不受欢迎的。 (2认同)

小智 10

理解为什么一定是这种情况的一个简单方法是考虑如果我们在中编写一个辅助函数会发生什么app/js/helper/logfetch.js

// app/js/helper/logfetch.js
function logFetch(resource) {
    console.log('Fetching', resource);
    return fetch(resource);
}
Run Code Online (Sandbox Code Playgroud)

现在,考虑一下如果我们使用 logFetch from 会发生什么app/js/app.js

// app/js/app.js
fetch('data.json');    // if this is relative to js/, then ...
logFetch('data.json'); // should this be relative to js/ or js/helper/?
Run Code Online (Sandbox Code Playgroud)

我们可能希望这两个调用返回相同的内容 - 但如果 fetch 相对于所包含的文件,那么 logFetch 将请求而js/helper/data.json不是与 fetch 一致的内容。

如果 fetch可以感知从何处调用它,那么要实现 logFetch 等帮助程序库,JavaScript需要一系列新的调用方位置感知功能。

相反,执行相对于 HTML 文件的提取可提供更高的一致性。

CSS 的工作方式有所不同,因为它没有方法调用的复杂性:您无法创建转换其他 CSS 模块的“辅助 CSS 模块”,因此相对路径的想法在概念上更加清晰。

  • 这应该是公认的答案。OP 要求“解释为什么会出现这种情况”,而这个答案真正解释了“为什么”。 (2认同)