公司的客户端使用了GitHub - chromiumembedded/cef 。所以,有时候不得不写前端代码。有时候逻辑很清晰,但在语法上折腾半天。
这周在一个Fetch API - MDN 调用上踩了坑,所以去读了它的文档,顺道整理下。
在开始之前,最好和vue混个脸熟,知道它是干啥的。简单的刷下视频快速入门下:2022年最新版Vue3全套教程
本文完整的示例代码见:1-fetch-demo
参考下:Windows 环境搭建 Vue 开发环境 | 小决的专栏、十分钟上手-搭建vue2.0开发环境
安装Node.js。安装之后,验证安装成功。
node.exe -v
v16.17.0
全局安装vue-cli脚手架 - 略
npm.cmd install --global vue-cli
4 vulnerabilities (2 moderate, 2 high)
To address all issues (including breaking changes), run:
npm audit fix --force
npm WARN using --force Recommended protections disabled.
npm ERR! code ENOLOCK
npm ERR! audit This command requires an existing lockfile.
npm ERR! audit Try creating one first with: npm i --package-lock-only
npm ERR! audit Original error: loadVirtual requires existing shrinkwrap file
npm.cmd remove -g @vue/cli
npm init vue@latest
Need to install the following packages:
create-vue@3.3.2
Ok to proceed? (y) y
Vue.js - The Progressive JavaScript Framework
√ Project name: ... fetch-demo
√ Add TypeScript? ... No / Yes
√ Add JSX Support? ... No / Yes
√ Add Vue Router for Single Page Application development? ... No / Yes
√ Add Pinia for state management? ... No / Yes
√ Add Vitest for Unit Testing? ... No / Yes
√ Add Cypress for both Unit and End-to-End testing? ... No / Yes
√ Add ESLint for code quality? ... No / Yes
Scaffolding project in E:\code\tmp\fetch-demo...
Done. Now run:
cd fetch-demo
npm install
npm run dev
vscode安装插件。参考:VSCode 开发Vue必备插件
和windows类似,只不过ubutnu20自带了node,但是node版本比较低。参考如何快速切换和管理node版本,选择nvm进行版本管理。
wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.2/install.sh | bash
nvm -v
nvm install 18
nvm use 18
node -v
v18.12.1
顺手再切换下源吧。(因为走**的时候,DNS解析registry.npmjs.org失败了)
npm config get registry # 查看源
npm config set registry https://registry.npm.taobao.org # 设置仓库
创建下项目。
npm init vue@latest
Fetch API - MDN 提供了一个获取资源的接口(包括跨域请求)。fetch() 必须接受一个参数——资源的路径。无论请求成功与否,它都返回一个 Promise 对象。一个 Promise 对象代表一个在这个 promise 被创建出来时不一定已知值的代理。它让你能够把异步操作最终的成功返回值或者失败原因和相应的处理程序关联起来。(类似于std::promise - cppreference.com,没用过这个,std::future - cppreference.com的接口层次高些。)
关于fetch的介绍,还可以参考:Fetch API 教程 - 阮一峰的网络日志、promise - How to use fetch in TypeScript - Stack Overflow
代码很简单,访问一个地址,并获取响应状态码。(原本是想访问一个页面,然后浏览器展示fetch到的页面,这似乎不容易,至少对于我这个web菜狗,是做不到的)
<script lang="ts">
export default {
data() {
return {
url: String,
page: String
}
},
methods: {
async copy_page(url:string) : Promise<any> {
this.url = url
this.page = await fetch(this.url,{
method: 'get',
headers: {
'Content-Type': 'application/json',
},
}).then(resp =>{
console.debug(resp)
return resp.status
})
},
},
mounted() {
this.page = this.copy_page('/baidu/s?wd=fetch-demo')
console.log('load app vue')
}
}
</script>
<template>
<div>{{page}}</div>
</template>
<style scoped>
</style>
plate>
<style scoped>
</style>
代码运行的时候,会出现跨域请求的问题。
参考:跨源资源共享(CORS) - HTTP | MDN、跨域的解决方法有哪些?JSONP的原理?CORS怎么使用?Nginx如何设置? - BiliBili
跨域请求的原理是,浏览器执行当前页面服务器的请求,而请求的资源却在另一个域名的服务器上。跨域请求,可能出现CSRF攻击_大1234草的博客-CSDN博客的问题。但,必须可以在不同站点间跳来跳去,比如超链接,否则站点会成为一个个孤岛。
vite可以通过proxy来解决跨站问题,可参考:vite-proxy-BiliBili、开发服务器选项 | Vite 官方中文文档
配置如下。
export default defineConfig({
xxxx,
xxxx,
server: {
proxy:{
'/baidu':{
target:'https://www.baidu.com',
changeOrigin:true,
rewrite: path => path.replace(/^\/baidu/,'')
},
'/koal':{
target:'http://www.koal.com',
changeOrigin:true,
rewrite: path => path.replace(/^\/koal/,'')
}
}
}
})
官方文档中写道,是使用 http-proxy完成代理。
猜测代理过程大概是这样。浏览器去执行请求,是跨站。那浏览器把锅推回去,让服务器自己去请求其他服务器的资源。请求结束之后,再将内容返回给浏览器就好了。是一个本地的反向代理过程。