首页
Search
1
Linux 下 Bash 脚本 bad interpreter 报错的解决方法
70 阅读
2
Arch Linux 下解决 KDE Plasma Discover 的 Unable to load applications 错误
52 阅读
3
Arch Linux 下解决 KDE Plasma Discover 的 Unable to load applications 错误
42 阅读
4
如何在 Clash for Windows 上配置服务
40 阅读
5
如何在 IOS Shadowrocket 上配置服务
40 阅读
clash
服务器
javascript
全部
游戏资讯
登录
Search
加速器之家
累计撰写
1,061
篇文章
累计收到
0
条评论
首页
栏目
clash
服务器
javascript
全部
游戏资讯
页面
搜索到
1061
篇与
的结果
2024-10-20
nodejs 中如何校验请求中的 referer
我们在写 nodejs 服务时,经常需要校验请求中的 referer 字段。有些只需要校验 referer 中的 hostname 是否合法即可,有些则要校验 referer 中的协议或者端口。同时,接收到的 referer 字段最后还有个斜杠/,若我们使用完全相等判断法,可能会造成前后端联调不太方便。那么该如何更方便的校验 referer 呢?这就要用到我们在上一篇文章如何在 nodejs 的原生 http 服务中获取请求参数中讲到的URL构造函数,这个函数可以把 url 拆分成几部分,然后我们可以分别进行判断。如,我们设置几个 referer 白名单,同时不限制端口:// 从headers中获取到referer const { referer, origin, host } = req.headers; const selfOrigin = referer || origin || `//${host}`; // 只匹配中间的域名,协议和端口均忽略 const { hostname } = new URL(selfOrigin, 'http://localhost/'); // 设置访问白名单 const ALLOW_HOSTS = ['joke.qq.com', 'news.qq.com']; // 当不在白名单中时,则返回403 if (!ALLOW_HOSTS.includes(hostname)) { res.status(403).end('403 forbidden'); next('403 forbidden'); } 若需要校验端口时,可以再加上端口的判断,如端口只能是空、80和443等。
2024年10月20日
5 阅读
0 评论
0 点赞
2024-10-20
nextjs 如何不显示next_data的数据
nextjs 提供了 getServerSideProps 方法(之前叫 getInitialProps 方法),用于在渲染页面之前请求数据,但 nextjs 框架为了能够前后端保持同步,会将请求到的数据,通过一个 script 标签传给前端: 但有时候,我们并不想把一些原始数据暴露到前端页面中,如一些博客网站、新闻网站等,基本以展示数据为主,没有同构的需要。所以,如何隐藏掉__NEXT_DATA__中的数据,只展示构建好的 html 呢? 1. 使用方式 # 在 nextjs 的 GitHub 上,有一个 pull request: Allow disabling runtime JS in production for certain pages (experimental) #11949,讨论了这个功能。从nextjs@9.4.0版本开始,为 pages 目录中的组件提供了一个unstable_runtimeJS的配置,当设置该参数为 false 后,则不会再展示__next_data__中的数据。 注意该设置只在process.env.NODE_ENV==='production'时生效。 不过,它带来的副作用也很大,它会导致整个页面实现的前端功能(如点击事件等)全部失效,包括该组件引用的子组件。// pages/home.tsx const Home = ({ nick, age }) => { const handleClick = () => { console.log('home click'); }; return ( home {nick} {age} ); }; // 移除__next_data__,移除所有前端的js export const config = { unstable_runtimeJS: false, }; // https://www.nextjs.cn/docs/basic-features/pages#%E6%9C%8D%E5%8A%A1%E5%99%A8%E7%AB%AF%E6%B8%B2%E6%9F%93 export const getServerSideProps = async (context: any) => { const { nick, age } = await fetch('api'); return { props: { nick, age } }; }; 最终渲染出来的 html 结构: 2. 副作用 # 从上图中可以看到,unstable_runtimeJS副作用很少很大的,虽不再展示 getServerSideProps 方法中返回的数据,但整个页面所有的 script 标签也都没了。这就造成该组件和它所有的子组件,均没有了前端功能。 3. 解决方案 # 若真的想在前端加载 js,也是有办法的。那就是使用 script 标签,自己加载 js 链接或者内容。 3.1 外链的方式 # 假如我们把要加载的前端 js 放在了https://cdn.bootcdn.net/ajax/libs/axios/0.26.0/axios.js链接中,直接通过 script 标签的 src 引入即可:const Home = ({ nick, age }) => { return ( home {nick} {age} ); }; 3.2 内敛的方式 # 都是同一个项目的代码,单独把某一部分拿出去再构建,实在是不方便。这里可以把 js 代码转成字符串,写到 script 标签中。 3.2.1 dangerouslySetInnerHTML 属性 # 使用 script 标签的 dangerouslySetInnerHTML 属性: console.log(Date.now()));`, }} > 3.2.2 script 标签的内容区 # {`document.querySelector('h1')?.addEventListener('click', () => console.log(Date.now()));`} 3.2.3 利用 function 的 toString() # 方法名调用 toString()会该方法的函数体,这里我们封装成一个立即执行函数的形式:const Home = ({ nick, age }: any) => { // 所有前端要执行的js,放在这里面 const bootstrap = () => { if (typeof document === 'undefined') { return; } document.querySelector('h1')?.addEventListener('click', () => console.log(Date.now())); }; return ( home {nick} {age} ); }; 最终编译后的效果: 4. 总结 # 从上面的分析也能看到,不是特别必要的时候,最好还是不要用unstable_runtimeJS禁用 js,否则为了实现相同的功能,就要用很多的奇技淫巧来弥补。
2024年10月20日
10 阅读
0 评论
0 点赞
2024-10-20
前端中对 url 的一些常用操作
我们平时操作 url 也比较多,如获取 url 中的参数,拼接 url 等,这里我们简单汇总下对 url 的常用操作。 1. 获取 url 中的参数 # 现在浏览器已经支持URLSearchParams对象了,我们可以直接用该方法获取参数。而且该方法的浏览器兼容性也非常好:// 获取当前url中的参数 const getQueryString = (name) => { const searchParams = new URLSearchParams(location.search); return searchParams.get(name); }; 若您的项目要兼容的范围更广,可以参考这篇文章中的方法:javascript 获取 URL 链接和 js 链接中的参数。 2. 获取 url 的域名、路径、referer 等 # 以前我们要获取一个 url 其中的某一部分,还得创建一个a标签来进行解析,如使用 DOM 中的 a 标签解析 url这篇文章中讲解到的。不过现在浏览器也提供了URL对象,获取 url 的某一部分也更简便了。 若只给 URL 传入一个参数,这个 url 必须是绝对地址,即需要携带协议,如 http://, https://, file://等;若不确定第一个参数中是否携带协议和主机信息,我们可以使用第二个参数进行补充。 若我们不确定要解析的参数是不是绝对地址,那就传第 2 个参数进行备用,如:const param = '/post/nodejs/nodejs-http-getquery-qwurz4.html?nick=wenzi'; // 若param是绝对地址,则直接使用,否则用第2个参数进行拼接 // 若拼接后依然不是绝对地址,则抛出TypeError异常 const uu = new URL(param, 'http://localhost'); console.log(uu); 执行后的结果(host 与 hostname 字段的区别:若链接中有端口时,host 字段会拼接上端口;如端口为 8080 时,则 host 字段为localhost:8080,hostname 为localhost):解析后,获取 hostname, path 等就非常方便了,不受其他字段的干扰。具体使用,也可以参考文章如何在 nodejs 的原生 http 服务中获取请求参数。 3. 修改 URL 的某一部分 # 对于一个完整的 URL,有时候我们只想修改其中的某一部分,而不影响其他部分,这个怎么处理呢?比如我们要把链接路径(pathname)中所有的字符a改为字符b,若使用正则的话,则可能把参数和 hash 路由中的字符也给替换掉。或者把当前链接中所有的参数,然后跳转到下一个链接。先把 url 拆分,再进行拼装,其实也可以,但并不是最好的方案。这里用URL的实例化对象,直接更新某一部分,然后最后返回.href属性即可。const replaceUrlPath = (url: string) => { const uu = new URL(url, 'http://localhost'); uu.pathname = uu.pathname.replace(/a/g, 'b'); // 对url的某一部分进行处理 return uu.href; }; replaceUrlPath('https://www.xiabingbao.com/post/javascript/url-handler-r7scei.html?a=b#main?c=123'); // https://www.xiabingbao.com/post/jbvbscript/url-hbndler-r7scei.html?a=b#main?c=123 4. 判断 url 地址是否为绝对地址 # 我们在这里简单地认为只要 url 有协议,它就是绝对地址,无论是什么协议(双斜杠//也算作绝对地址):const isAbsolute = (url) => /^([a-z][a-z\d+\-.]*:)?\/\//i.test(url); 运行的结果:isAbsolute('http://localhost'); // true isAbsolute('https://localhost'); // true isAbsolute('file://localhost'); // true isAbsolute('qqnews://localhost'); // true isAbsolute('//localhost'); // true isAbsolute('/api/list'); // false 5. 拼接 URL # 拼接 url 时,尤其要注意前后的斜杠/:/** * Creates a new URL by combining the specified URLs * * @param {string} baseURL The base URL * @param {string} relativeURL The relative URL * @returns {string} The combined URL */ const combineURLs = (baseURL, relativeURL) => { // 将baseURL最后的斜杠和relativeURL最前面的斜杠去掉 return relativeURL ? `${baseURL.replace(/\/+$/, '')}/${relativeURL.replace(/^\/+/, '')}` : baseURL; }; 使用:combineURLs('https://www.xiabingbao.com/post/', '/request/axios-some-utils.html'); // 得到: https://www.xiabingbao.com/post/request/axios-some-utils.html 我们在这里仅仅是进行简单的拼接,并不保证拼接后的 url 的合法性。 6. http 协议转成 https # 这里用正则判断下就可以,若是以http://开头的,则替换成https://:/** * 将http链接转换为https链接 * @param url 要转换的http链接 */ const http2https = (url: string): string => { // 若不是以 http:// 开头,则原样返回 return url.replace(/^http:\/\//, 'https://'); }; 7. encodeURI 和 encodeURIComponent 的区别 # encodeURI 和 encodeURIComponent 的区别在于前者被设计来用于对完整 URL 进行 URL Encode,于是 URL 中的功能字符,比如&, ?, /, =等等这些并不会被转义;而后者被设计来对一个 URL 中的值进行转义,会把这些功能字符也进行转义。 escape 和 unescape 两个方法已被废弃,应当避免使用。 我们看着例子:const url = 'https://www.xiabingbao.com/post/react/nextjs-server-client-build-qxpzwi.html#1. 只在浏览器端使用的模块'; encodeURI(url); // https://www.xiabingbao.com/post/react/nextjs-server-client-build-qxpzwi.html#1.%20%E5%8F%AA%E5%9C%A8%E6%B5%8F%E8%A7%88%E5%99%A8%E7%AB%AF%E4%BD%BF%E7%94%A8%E7%9A%84%E6%A8%A1%E5%9D%97 encodeURIComponent(url); // https%3A%2F%2Fwww.xiabingbao.com%2Fpost%2Freact%2Fnextjs-server-client-build-qxpzwi.html%231.%20%E5%8F%AA%E5%9C%A8%E6%B5%8F%E8%A7%88%E5%99%A8%E7%AB%AF%E4%BD%BF%E7%94%A8%E7%9A%84%E6%A8%A1%E5%9D%97 encodeURI 编译后的 url 可以正常访问,而 encodeURIComponent 编译后的字符串大部分都是作为参数。
2024年10月20日
10 阅读
0 评论
0 点赞
2024-10-20
前端项目中如何区分环境
一个项目从开发到上线,大致要经过本地开发、测试环境、预发布环境和正式环境。那么在代码中如何区分这几个环境,然后再与对应的后端接口进行对接呢?我们经历多几个项目的磨练后,总结出几个区分不同环境的方法。 从 URL 的域名进行区分; 构建时传入不同的全局变量; 容器提前定义好全局变量(一般后端服务使用); 下面我们来一一进行讲解。我们先来定义几个环境变量:enum EnvType { LOCAL = 'local', // 本地开发环境 TESTING = 'testing', // 测试环境 PRE = 'pre', // 预发布环境 PRODUCTION = 'production', // 正式环境 } 1. 从 URL 的域名进行区分 # 若不同环境使用不同的域名,最简单的就是从 URL 域名进行区分。我们从 URL 中获取到 hostname 或 origin,然后进行判断。// 通过url检测环境 const checkUrlHost = (): EnvType => { const { hostname } = window.location || { hostname: null }; if (/test/.test(hostname)) { return EnvType.TESTING; } if (/pre/.test(hostname)) { return EnvType.PRE; } if (/local/.test(hostname)) { return EnvType.LOCAL; } return EnvType.PRODUCTION; }; 注意:不要用整个 URL 地址来进行匹配,因为中间的路径或者携带的参数,可能会干扰到判断。最开始我们还不能区分域名时,都是在同一个域名里进行开发,然后用不同的路径来区分,不过代码里用的是location.href来区分。然后我们参数里要带着用户的昵称,这个用户的昵称正好有个test的字样。导致项目把这个链接识别成了测试环境,然后就去请求测试环境的接口了。 2. 构建时传入不同的全局变量 # 现在我们发布项目时,都会先进行构建,然后再把 html 发布出去。那么我们就可以在构建时,把当前要发布的环境对应的变量传进去。如何传入全局变量,还得看您正在使用的框架,如 React 的脚手架 create-react-app,传入的全局变量必须以REACT_APP_开头;Vue 的脚手架 vue-cli,传入的全局变量必须以VUE_APP_开头。我们以 create-react-app 为例,使用REACT_APP_SITE_ENV来指定所在的环境。构建时:# 本地开发环境 $ REACT_APP_SITE_ENV=local npm run start # 测试环境 $ REACT_APP_SITE_ENV=testing npm run build # 预发布环境 $ REACT_APP_SITE_ENV=pre npm run build # 正式环境 $ npm run build # 不传入 $ REACT_APP_SITE_ENV=production npm run build # 或传入production 代码中获取该全局变量:// 通过全局变量来检测环境 const getEnv = (): EnvType => { const { REACT_APP_SITE_ENV }: any = process.env; // 命令行传入 // REACT_APP_SITE_ENV只能是EnvType中的值 // 若没有传入,或者不是这里面的几个值,则返回production if (REACT_APP_SITE_ENV) { // eslint-disable-next-line no-restricted-syntax for (const key in EnvType) { const env = (EnvType as any)[key]; if (env === REACT_APP_SITE_ENV) { return REACT_APP_SITE_ENV; } } } return EnvType.PRODUCTION; }; 这里我们在构建流水线里指定 REACT_APP_SITE_ENV 为不同的值即可。 3. 容器提前定义好全局变量 # 前端代码一般是只有构建过程,但后端代码(如 nodejs 等),通常是【启动】或者【构建 + 启动】的过程,若有构建过程,则像上面那样在流水线里指定全局变量即可。而启动这个程序一般是在容器里启动的,而流水线里的全局变量在构建完成后就失效了,留不到启动这一步。因此,若是在容器中启动的程序,您可以在容器里配置好全局变量,这样程序在启动时,就自动能够获取到了。至于怎么配置,还得看您公司自己的配置。如我们的配置是: 4. 总结 # 这里我们主要讲解了下如何在项目中来区分环境,很多开发者还会再额外地定义一些变量或方法,来直接使用,如:// 定义变量 export const IS_LOCALENV = ENV === EnvType.LOCAL; // 是否是本地环境 export const IS_TESTENV = ENV === EnvType.TESTING; // 是否测试环境 export const IS_PREENV = ENV === EnvType.PRE; // 是否是预发布环境 export const IS_PRODENV = ENV === EnvType.PRODUCTION; // 是否是正式环境 // 定义方法 export const isPro = () => ENV === EnvType.PRODUCTION; // 是否是正式环境 或许未来新的框架或者部署流程,还是出现新的定义环境的方式。
2024年10月20日
4 阅读
0 评论
0 点赞
2024-10-20
第7页
Front-end Engineer,前端开发工程师目前是一名前端开发工程师,主要负责前端规划、框架与架构、前端性能优化。专注前端技术,关注交互体验,擅长web ajax开发。坚信前端工程师的价值是最终能把技术和设计完美结合在一起。用最新的技术方案巧妙地帮助这些设计得以实现。
2024年10月20日
3 阅读
0 评论
0 点赞
1
...
47
48
49
...
213