JavaScript ||将 API 与 ES6 模块一起使用
JavaScript || Using API with ES6 modules
我目前正在练习在 JS(vanilla)中使用 API 和 es6 模块。
app.js
import Game from './model/Game';
const proxy = 'https://cors-anywhere.herokuapp.com/';
let key = 'MY_API_KEY_PRIVATE'; //kept private for Whosebug
let steamID = '76561197996900532';
getOwnedGames();
async function getOwnedGames() {
try {
const result = await fetch(`${proxy}http://api.steampowered.com/IPlayerService/GetOwnedGames/v0001/?key=${key}&steamid=${steamID}&format=json&include_appinfo=true`);
const data = await result.json();
let gamesList = data.response.games;
console.log(gamesList);
} catch(error) {
console.error(error);
}
}
.
Game.js
export class Game {
}
现在无需使用 import GotGames from './model/Game';
即可运行,但会出现以下错误:
Uncaught SyntaxError: Cannot use import statement outside a module
通过在 HTML 的脚本标记中添加 type="module"
,我在这个 space 中看到了类似的问题,但是会出现以下错误:
Access to script at 'my_file_path' from origin 'null' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https.
为什么添加 type="module" 会影响我的 API 调用,如何实现?这与要求 Node.js 偶然安装 webpacks 有什么关系吗?
似乎通过在脚本中包含 type="module" 的 export default class Game
中添加 default
,它似乎又可以正常工作了。
是否有关于为什么会这样的解释?这样我就可以理解了。
编辑:这似乎仅在 LiveServer 中的 html 文件为 运行 时有效(充当本地服务器的 VS Code 分机)
而当我手动 运行(单击打开 index.html)文件时出现相同的错误:
Access to script at 'file:///*path_to_.js_file*
' from origin 'null' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https.
你的问题实际上是一个非常广泛的问题,但我会尝试澄清它的一些重要方面。
-剧透开始-
Webpack.
-剧透结束-
请注意,即使它不是 beginner-friendly 而出名,也有人将它与 Babel 和 React 一起称为 Web 开发技术的最前沿。因此值得至少研究一次。简而言之,它将把你的 ES 模块转换成一个自定义系统(用普通的旧 JavaScript 编写),从技术上讲,它与所有浏览器兼容,并将保留功能以及许多其他优点。
但是,为了简单起见,您可能想要使用像 React 这样的框架,它在后台使用 Webpack,这样您就不必直接处理它。
我真的建议你 this Medium article 去发现一些关于 JavaScript 和 NodeJS 中模块历史的有趣事实。
最后,我们都同意 ES6 模块是未来,但是,即使在解决了您的具体问题之后,您也会遗憾地发现 ES6 模块是一个非常新的标准,目前它的浏览器相对较差支持。
回答您的问题:
默认情况下,浏览器不会将 JavasScript 文件解释为模块,因此您必须在脚本标签中使用 type="module"
属性显式声明它们。这显然是您遇到第一个错误的原因。
要正确导入 "Game.js" 模块,您必须 re-write 您的导入语句如下: import {Game} from './model/Game';
因为您进行了命名导出。正如评论中所写,在 MDN 上阅读一些关于 import/export 的内容,你会更清楚。
最后,CORS 错误很可能是由服务器配置错误引起的。特别是 headers。您可能想尝试将 Access-Control-Allow-Origin
header 设置为 *
或您的特定服务器名称,这样新请求将 Origin
header 不同于 null
.
我希望这会为您指明一条扩展知识的好途径。
* 编辑:要解决单击打开文件时有关错误的评论中的问题,我建议使用以下不太知名的元标记 <meta http-equiv="Access-Control-Allow-Origin" content="*">
来模拟 http header没有服务器时。我不确定它是否会起作用,但从技术上讲它应该,请在评论中让我知道,因为我很好奇。
见this
我目前正在练习在 JS(vanilla)中使用 API 和 es6 模块。
app.js
import Game from './model/Game';
const proxy = 'https://cors-anywhere.herokuapp.com/';
let key = 'MY_API_KEY_PRIVATE'; //kept private for Whosebug
let steamID = '76561197996900532';
getOwnedGames();
async function getOwnedGames() {
try {
const result = await fetch(`${proxy}http://api.steampowered.com/IPlayerService/GetOwnedGames/v0001/?key=${key}&steamid=${steamID}&format=json&include_appinfo=true`);
const data = await result.json();
let gamesList = data.response.games;
console.log(gamesList);
} catch(error) {
console.error(error);
}
}
.
Game.js
export class Game {
}
现在无需使用 import GotGames from './model/Game';
即可运行,但会出现以下错误:
Uncaught SyntaxError: Cannot use import statement outside a module
通过在 HTML 的脚本标记中添加 type="module"
,我在这个 space 中看到了类似的问题,但是会出现以下错误:
Access to script at 'my_file_path' from origin 'null' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https.
为什么添加 type="module" 会影响我的 API 调用,如何实现?这与要求 Node.js 偶然安装 webpacks 有什么关系吗?
似乎通过在脚本中包含 type="module" 的 export default class Game
中添加 default
,它似乎又可以正常工作了。
是否有关于为什么会这样的解释?这样我就可以理解了。
编辑:这似乎仅在 LiveServer 中的 html 文件为 运行 时有效(充当本地服务器的 VS Code 分机) 而当我手动 运行(单击打开 index.html)文件时出现相同的错误:
Access to script at '
file:///*path_to_.js_file*
' from origin 'null' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https.
你的问题实际上是一个非常广泛的问题,但我会尝试澄清它的一些重要方面。
-剧透开始-
Webpack.
-剧透结束-
请注意,即使它不是 beginner-friendly 而出名,也有人将它与 Babel 和 React 一起称为 Web 开发技术的最前沿。因此值得至少研究一次。简而言之,它将把你的 ES 模块转换成一个自定义系统(用普通的旧 JavaScript 编写),从技术上讲,它与所有浏览器兼容,并将保留功能以及许多其他优点。
但是,为了简单起见,您可能想要使用像 React 这样的框架,它在后台使用 Webpack,这样您就不必直接处理它。
我真的建议你 this Medium article 去发现一些关于 JavaScript 和 NodeJS 中模块历史的有趣事实。
最后,我们都同意 ES6 模块是未来,但是,即使在解决了您的具体问题之后,您也会遗憾地发现 ES6 模块是一个非常新的标准,目前它的浏览器相对较差支持。
回答您的问题:
默认情况下,浏览器不会将 JavasScript 文件解释为模块,因此您必须在脚本标签中使用 type="module"
属性显式声明它们。这显然是您遇到第一个错误的原因。
要正确导入 "Game.js" 模块,您必须 re-write 您的导入语句如下: import {Game} from './model/Game';
因为您进行了命名导出。正如评论中所写,在 MDN 上阅读一些关于 import/export 的内容,你会更清楚。
最后,CORS 错误很可能是由服务器配置错误引起的。特别是 headers。您可能想尝试将 Access-Control-Allow-Origin
header 设置为 *
或您的特定服务器名称,这样新请求将 Origin
header 不同于 null
.
我希望这会为您指明一条扩展知识的好途径。
* 编辑:要解决单击打开文件时有关错误的评论中的问题,我建议使用以下不太知名的元标记 <meta http-equiv="Access-Control-Allow-Origin" content="*">
来模拟 http header没有服务器时。我不确定它是否会起作用,但从技术上讲它应该,请在评论中让我知道,因为我很好奇。
见this