首页

前端直接生成GIF动态图实践

前端达人

前言

去年在博客中发了两篇关于GIF动态生成的博客,GIF图像动态生成-JAVA后台生成基于FFmpeg的Java视频Mp4转GIF初探,在这两篇博客中都是采用JAVA语言在后台进行转换。使用JAVA的同学经过自己的改造和开发也可以应用在项目上。前段时间有朋友私下问,有没有不使用Java,甚至不依赖于后台的,直接基于前端的GIF动图生成,有没有这种技术方案。博主个人对前端不是很擅长,后来也是在github上自习搜索了一番,发现了一个比较有意思的,可以直接在前端使用的gif动态图生成组件。本文重点聊聊gif.js组件,介绍一下gif这个组件的基本原理,在生产中如何进行使用。

一、GIF.JS简介

1、gif.js是什么

gif.js在github的地址是:gif.js,打开它的官方网站,可以看到如下的介绍:

作为一款成熟的插件,在github上有4.5k的star,足以说明它的受欢迎程度。而且gif.js采用的是宽松的MIT协议,您可以随意下载这个插件,再此基础之上改造成自己的工具供别人使用。使用git clone将工程下载到本地后,可以看到gif.js的初始目录。

2、gif.js基础依赖

打开工程目录的package.json文件,这里定义了文件基础依赖。打开后可以看到如下的定义信息:


  1. {
  2. "name": "gif.js",
  3. "version": "0.2.0",
  4. "description": "JavaScript GIF encoding library",
  5. "author": "Johan Nordberg <code@johan-nordberg.com>",
  6. "main": "index.js",
  7. "repository": "https://github.com/jnordberg/gif.js.git",
  8. "devDependencies": {
  9. "browserify": "^13.1.1",
  10. "coffeeify": "^2.1.0",
  11. "exorcist": "^0.4.0",
  12. "uglify-js": "^2.7.5"
  13. },
  14. "scripts": {
  15. "prepublish": "./bin/build"
  16. },
  17. "browser": "./dist/gif.js",
  18. "keywords": [
  19. "gif",
  20. "animation",
  21. "encoder"
  22. ],
  23. "license": "MIT",
  24. "readmeFilename": "README.md"
  25. }

3、关键基础类解析

在GIFEncoder.js文件中定义了gif.js对象了基本一些属性,在上面的目录中打开目标文件后,可以看到属性定义方法:

核心方法API说明:您可以使用构造方法或者使用setOptions()方法类设置相关的属性。详情可以看下面的说明:

Name

Default

Description

repeat

0

repeat count, -1 = no repeat, 0 = forever

quality

10

pixel sample interval, lower is better

workers

2

number of web workers to spawn

workerScript

gif.worker.js

url to load worker script from

background

#fff

background color where source image is transparent

width

null

output image width

height

null

output image height

transparent

null

transparent hex color, 0x00FF00 = green

dither

false

dithering method, e.g. FloydSteinberg-serpentine

debug

false

whether to print debug information to console

二、gif.js实战

下面采用具体的代码进行一个实际例子的实践。

1、新建html工程

这里以video2.html为例,在这个工程中引入了gif.js和gif.worker.js。工程目录如下,Jquery.js作为非必须依赖。


  1. <head>
  2. <meta charset="utf-8">
  3. <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
  4. <title>视频转GIF</title>
  5. <meta name="description" content="Full-featured JavaScript GIF encoder that runs in your browser.">
  6. <meta name="keywords" content="gif, encoder, animation, browser, unicorn">
  7. <meta name="viewport" content="width=device-width">
  8. <meta property="og:title" content="gif.js">
  9. <meta property="og:url" content="http://jnordberg.github.io/gif.js">
  10. <meta property="og:description" content="Full-featured JavaScript GIF encoder that runs in your browser.">
  11. <meta property="og:type" content="website">
  12. <link rel="stylesheet" href="main.css">
  13. <script src="gif.js?v=3"></script>
  14. <script src="video.js?v=3"></script>
  15. </head>

2、定义gif对象


  1. gif = new GIF({
  2. workers: 4,
  3. workerScript: 'gif.worker.js',
  4. width: 600,
  5. height: 337
  6. });

定义好了gif对象之后,还需要定义相应的响应事件,如下代码所示:


  1. sample.addEvent('change', sampleUpdate);
  2. button.addEvent('click', function() {
  3. video.pause();
  4. video.currentTime = 0;
  5. gif.abort();
  6. gif.frames = [];
  7. return video.play();
  8. });
  9. gif.on('start', function() {
  10. return startTime = now();
  11. });
  12. gif.on('progress', function(p) {
  13. return info.set('text', "rendering: " + (Math.round(p * 100)) + "%");
  14. });
  15. gif.on('finished', function(blob) {
  16. var delta, img;
  17. img = document.id('result');
  18. img.src = URL.createObjectURL(blob);
  19. delta = now() - startTime;
  20. console.log("done in\n" + ((delta / 1000).toFixed(2)) + "sec,\nsize " + ((blob.size / 1000).toFixed(2)) + "kb");
  21. return info.set('text', "done in\n" + ((delta / 1000).toFixed(2)) + "sec,\nsize " + ((blob.size / 1000).toFixed(2)) + "kb");
  22. });

代码有点长,这里不一一列出,需要源代码的可以私信。

3、最后效果

使用nginx进行静态发布后,可以看到如下的效果:

点击执行按钮后,在网页下面生成gif动态图,如下所示:

实际生成的动态图会根据原始视频的大小,画质质量,清晰度等因素影响,执行时间也会有影响。在实际项目中需要根据需要调整相应的参数才可以。

4、执行分析

以完成后渲染动图为例讲解合成过程,

可以在变量区看到客户端开启了多个Worker进行并行处理。

在这里进行数据合并处理,如下:

最终合成gif图片,在html中进行dom渲染。

三、总结

以上就是本文的主要内容,本文重点介绍了一款前端基于Javascript的gif.js生成插件,分析了它的源码结构,最后通过一个实例进行了案例讲解,帮您快速的了解和掌握这个组件,文章行文仓促,如有错误,请留言交流。



蓝蓝设计建立了UI设计分享群,每天会分享国内外的一些优秀设计,如果有兴趣的话,可以进入一起成长学习,请加微信ban_lanlan,报下信息,蓝小助会请您入群。欢迎您加入噢~~

希望得到建议咨询、商务合作,也请与我们联系01063334945。 



分享此文一切功德,皆悉回向给文章原作者及众读者. 免责声明:蓝蓝设计尊重原作者,文章的版权归原作者。如涉及版权问题,请及时与我们取得联系,我们立即更正或删除。 



蓝蓝设计www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计、BS界面设计 、 cs界面设计 、 ipad界面设计 、 包装设计 、 图标定制 、 用户体验 、交互设计、 网站建设 平面设计服务UI设计公司、界面设计公司、UI设计服务公司、数据可视化设计公司、UI交互设计公司、高端网站设计公司、UI咨询、用户体验公司、软件界面设计公司

vite.config.js配置-解决跨域问题,以及@vitejs/plugin-vue等报错

前端达人

  • 开发环境

    在配置的过程中踩了很多坑,还是太菜,有些东西弄不明白什么意思。

    运行项目时的报错可直接到最下面看vite.config.js文件的注释

    目前项目用到的模块并不多,package.json文件如下

    
                                
    1. {
    2. "name": "PsWebV3Abb",
    3. "version": "0.0.0",
    4. "scripts": {
    5. "dev": "vite",
    6. "build": "vite build"
    7. },
    8. "dependencies": {
    9. "@vitejs/plugin-vue": "^1.0.0",
    10. "axios": "^1.2.1",
    11. "element-plus": "^2.2.26",
    12. "vite": "^4.0.3",
    13. "vue": "^3.0.4",
    14. "vue-router": "^4.1.5"
    15. },
    16. "devDependencies": {
    17. "@vue/compiler-sfc": "^3.0.4"
    18. }
    19. }

    其实主要还是这些模块的版本兼容问题

    vite的版本最开始是1.0.0,后面很多地方搞不下去了才卸载了重装新的版本

    当然还是建议仔细阅读一下官方文档,其实很多重要的点都讲的很清楚,只不过是遇到问题的时候才会注意到。官方文档请移步这里

    下面简单的说一下这个文件,

    首先是文件的位置,放在其他位置是无效的:

            

    运行vite项目的时候,就会自动解析根目录下面的这个文件

    我这里的主要目的还是解决项目运行时的跨域问题

    下面是封装的一个简单的请求示例,其中service是一个封装好的axios实例,可以指定一下baseurl,以及请求和响应拦截。

    其他的API都可以像这样通过给getItem添加方法的方式实现

    
                                
    1. import service from '../utils/requests.js'
    2. const getItem = {}
    3. getItem.getppitem = function (params) {
    4. return service.get('api/AutoSimple/getdata', params)
    5. }
    6. export default getItem

    vite.config.js 具体的配置如下

    
                                
    1. import { defineConfig } from 'vite'
    2. import vue from '@vitejs/plugin-vue'
    3. // import eslintPlugin from 'vite-plugin-eslint'
    4. // https://vitejs.dev/config/
    5. // 这个配置文件可能出现的问题:
    6. // 首先是此文件放置的位置
    7. // 1.未安装 @vitejs/plugin-vue
    8. // 处理方法:npm i @vitejs/plugin-vue@1.0.0
    9. // 由于本项目vite版本1.0限制,只能用了plugin-vue的1.0.0版本,但在运行的时候又导致了问题2,
    10. // 于是直接卸载vite重新安装最新的3.0.4,这个版本直接install plugin-vue仍然不行,还是要用1.0.0版本
    11. // 2.显示不存在函数 defineConfig
    12. // 在此之后npm run dev,又报了一个错:Cannot find module 'node:path'
    13. // 在掘金上看到是和node版本有关,更新后就可以正常运行了
    14. export default defineConfig({
    15. plugins: [
    16. vue()
    17. // 检查代码格式
    18. // eslintPlugin({
    19. // include: ['src/**/*.js', 'src/**/*.vue', 'src/*.js', 'src/*.vue']
    20. // })
    21. ],
    22. server: {
    23. // 默认打开的端口和本地
    24. // host: '0.0.0.0',
    25. port: 3000,
    26. https: false, // 不支持https
    27. proxy: {
    28. '/api': {
    29. target: 'http://10.200.20.80/BARCODESERVICE', // 实际请求地址
    30. changeOrigin: true, // 是否跨域
    31. rewrite: (path) => path.replace(/^\/api/, '') // 对什么类的服务器匹配
    32. },
    33. }
    34. }
    35. })

    生产环境

    在部署生产环境时,又遇到了两个问题:

    1.公共路径的问题

    客户环境是IIS服务器,为了节省端口,在部署的时候选择在同一个网站下添加多个应用程序的方式,这就使得在部署时,需要添加公共的基础路径,这一点在官方文档中有详细的说明。

     

    解决方案:

    在package.json中配置

    
                                
    1. "scripts": {
    2. "dev": "vite",
    3. "build": "vite build --base=/PsWebDand/ "
    4. }

    2.跨域无效的问题

    vite.config.js 中的server的proxy无效,此时跨域的问题需要通过在后端服务中配置来解决

    IIS服务器

    
                                
    1. <httpProtocol>
    2. <customHeaders>
    3. <add name="Access-Control-Allow-Headers " value="Content-Type,api_key,Authorization" />
    4. <add name="Access-Control-Allow-Methods" value="GET,POST,PUT,DELETE,OPTIONS" />
    5. <add name="Access-Control-Allow-Origin" value="*" />
    6. </customHeaders>
    7. </httpProtocol>
    蓝蓝设计建立了UI设计分享群,每天会分享国内外的一些优秀设计,如果有兴趣的话,可以进入一起成长学习,请加微信ban_lanlan,报下信息,蓝小助会请您入群。欢迎您加入噢~~
    希望得到建议咨询、商务合作,也请与我们联系01063334945。 

    分享此文一切功德,皆悉回向给文章原作者及众读者. 免责声明:蓝蓝设计尊重原作者,文章的版权归原作者。如涉及版权问题,请及时与我们取得联系,我们立即更正或删除。 

    蓝蓝设计www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计、BS界面设计 、 cs界面设计 、 ipad界面设计 、 包装设计 、 图标定制 、 用户体验 、交互设计、 网站建设 平面设计服务UI设计公司、界面设计公司、UI设计服务公司、数据可视化设计公司、UI交互设计公司、高端网站设计公司、UI咨询、用户体验公司、软件界面设计公司

javascript - proxy - 异常: ‘set‘ on proxy: trap returned falsish for property ‘message‘

前端达人

定义 Proxy 代理对象的 set 的时候,
要返回 return true 。

特别是在严格模式下,否则,会报错 'set' on proxy: trap returned falsish for property 'message'

在这里插入图片描述

# 应该如下

 let handler = { get(obj, property) { }, set(obj, property, value) { return true; } } new Proxy({}, handler); 
        
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
文章知识点与官方知识档案匹配,可进一步学习相关知识





蓝蓝设计建立了UI设计分享群,每天会分享国内外的一些优秀设计,如果有兴趣的话,可以进入一起成长学习,请加微信ban_lanlan,报下信息,蓝小助会请您入群。欢迎您加入噢~~

希望得到建议咨询、商务合作,也请与我们联系01063334945。 



分享此文一切功德,皆悉回向给文章原作者及众读者. 免责声明:蓝蓝设计尊重原作者,文章的版权归原作者。如涉及版权问题,请及时与我们取得联系,我们立即更正或删除。 



蓝蓝设计www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计、BS界面设计 、 cs界面设计 、 ipad界面设计 、 包装设计 、 图标定制 、 用户体验 、交互设计、 网站建设 平面设计服务UI设计公司、界面设计公司、UI设计服务公司、数据可视化设计公司、UI交互设计公司、高端网站设计公司、UI咨询、用户体验公司、软件界面设计公司

Vue的$emit传值

前端达人

$emit,父组件传data给子组件,子组件通过$emit来触发父组件中绑定在子组件身上的事件,达到改变父组件中的data的方法。下面介绍$emit传值的几种方法:

一:$emit传递单值

子组件Test.vue:


  1. <template>
  2. <div>
  3. <div>子组件</div>
  4. <button @click="changeFather">点击我向父组件传递参数</button>
  5. </div>
  6. </template>
  7. <script>
  8. export default {
  9. methods: {
  10. changeFather() {
  11. this.$emit("changeEvent",'1');
  12. }
  13. }
  14. };
  15. </script>
  16. <style>
  17. </style>

父组件:App.vue


  1. <template>
  2. <div id="app">
  3. <p>这是父组件</p>
  4. <div>{{myString}}</div>
  5. <Test @changeEvent="changeMyString" />
  6. </div>
  7. </template>
  8. <script>
  9. import Test from "./components/Test";
  10. export default {
  11. name: "App",
  12. components: { Test },
  13. data: function() {
  14. return {
  15. myString: ''
  16. };
  17. },
  18. methods: {
  19. changeMyString(val) {
  20. console.log(val);
  21. this.myString=val;
  22. }
  23. }
  24. };
  25. </script>
  26. <style>
  27. #app {
  28. font-family: Avenir, Helvetica, Arial, sans-serif;
  29. -webkit-font-smoothing: antialiased;
  30. -moz-osx-font-smoothing: grayscale;
  31. text-align: center;
  32. color: #2c3e50;
  33. margin-top: 60px;
  34. }
  35. </style>

点击按钮效果如图:

二:$emit传递多个值

子组件Test.vue:


  1. <template>
  2. <div>
  3. <div>子组件</div>
  4. <button @click="changeFather">点击我向父组件传递参数</button>
  5. </div>
  6. </template>
  7. <script>
  8. export default {
  9. methods: {
  10. changeFather() {
  11. this.$emit("changeEvent",'1','2');
  12. }
  13. }
  14. };
  15. </script>
  16. <style>
  17. </style>

父组件App.vue:


  1. <template>
  2. <div id="app">
  3. <p>这是父组件</p>
  4. <div>{{myString}}</div>
  5. <Test @changeEvent="changeMyString" />
  6. </div>
  7. </template>
  8. <script>
  9. import Test from "./components/Test";
  10. export default {
  11. name: "App",
  12. components: { Test },
  13. data: function() {
  14. return {
  15. myString: ''
  16. };
  17. },
  18. methods: {
  19. changeMyString(val0,val1) {
  20. console.log(val0,val1);
  21. this.myString=val0+val1;
  22. }
  23. }
  24. };
  25. </script>
  26. <style>
  27. #app {
  28. font-family: Avenir, Helvetica, Arial, sans-serif;
  29. -webkit-font-smoothing: antialiased;
  30. -moz-osx-font-smoothing: grayscale;
  31. text-align: center;
  32. color: #2c3e50;
  33. margin-top: 60px;
  34. }
  35. </style>

点击按钮,效果如下:

$emit传递多个值时,还可以采用数组的形式:

修改子组件Test.vue:


  1. <template>
  2. <div>
  3. <div>子组件</div>
  4. <button @click="changeFather">点击我向父组件传递参数</button>
  5. </div>
  6. </template>
  7. <script>
  8. export default {
  9. methods: {
  10. changeFather() {
  11. this.$emit("changeEvent",['1','2']);
  12. }
  13. }
  14. };
  15. </script>
  16. <style>
  17. </style>

父组件App.vue:


  1. <template>
  2. <div id="app">
  3. <p>这是父组件</p>
  4. <div>{{myString}}</div>
  5. <Test @changeEvent="changeMyString" />
  6. </div>
  7. </template>
  8. <script>
  9. import Test from "./components/Test";
  10. export default {
  11. name: "App",
  12. components: { Test },
  13. data: function() {
  14. return {
  15. myString: ''
  16. };
  17. },
  18. methods: {
  19. changeMyString(val) {
  20. console.log(val);
  21. this.myString=val[0]+val[1];
  22. }
  23. }
  24. };
  25. </script>
  26. <style>
  27. #app {
  28. font-family: Avenir, Helvetica, Arial, sans-serif;
  29. -webkit-font-smoothing: antialiased;
  30. -moz-osx-font-smoothing: grayscale;
  31. text-align: center;
  32. color: #2c3e50;
  33. margin-top: 60px;
  34. }
  35. </style>

点击按钮,效果如下:

三:子组件通过$emit传递给父组件传递值,并且父组件有自定义参数时:

子组件Test.vue:


  1. <template>
  2. <div>
  3. <div>子组件</div>
  4. <button @click="changeFather">点击我向父组件传递参数</button>
  5. </div>
  6. </template>
  7. <script>
  8. export default {
  9. methods: {
  10. changeFather() {
  11. this.$emit("changeEvent",1,2);
  12. }
  13. }
  14. };
  15. </script>
  16. <style>
  17. </style>

父组件:App.vue


  1. <template>
  2. <div id="app">
  3. <p>这是父组件</p>
  4. <div>{{myString}}</div>
  5. <Test @changeEvent="changeMyString('myParameter',...arguments)" />
  6. </div>
  7. </template>
  8. <script>
  9. import Test from "./components/Test";
  10. export default {
  11. name: "App",
  12. components: { Test },
  13. data: function() {
  14. return {
  15. myString: ''
  16. };
  17. },
  18. methods: {
  19. changeMyString(...args) {
  20. console.log(args);
  21. this.myString=args;
  22. }
  23. }
  24. };
  25. </script>
  26. <style>
  27. #app {
  28. font-family: Avenir, Helvetica, Arial, sans-serif;
  29. -webkit-font-smoothing: antialiased;
  30. -moz-osx-font-smoothing: grayscale;
  31. text-align: center;
  32. color: #2c3e50;
  33. margin-top: 60px;
  34. }
  35. </style>

点击按钮,效果图如下:





蓝蓝设计建立了UI设计分享群,每天会分享国内外的一些优秀设计,如果有兴趣的话,可以进入一起成长学习,请加微信ban_lanlan,报下信息,蓝小助会请您入群。欢迎您加入噢~~

希望得到建议咨询、商务合作,也请与我们联系01063334945。 



分享此文一切功德,皆悉回向给文章原作者及众读者. 免责声明:蓝蓝设计尊重原作者,文章的版权归原作者。如涉及版权问题,请及时与我们取得联系,我们立即更正或删除。 



蓝蓝设计www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计、BS界面设计 、 cs界面设计 、 ipad界面设计 、 包装设计 、 图标定制 、 用户体验 、交互设计、 网站建设 平面设计服务UI设计公司、界面设计公司、UI设计服务公司、数据可视化设计公司、UI交互设计公司、高端网站设计公司、UI咨询、用户体验公司、软件界面设计公司

vue中播放rtsp流

前端达人

实现vue中播放rtsp视频流的问题

背景:项目中通过摄像机提供的rtsp流来显示画面,但是在编写项目中,需要将rtsp实时流画面传输到web前端页面中。于是找了很多方法,都是后台转码转成rtmp来播放,现在大部分插件和浏览器都是支持使用rtmp播放视频流。而rtsp随着flash的退出而被复杂化了。网上都是1、通过ffmpeg转码后输出,2、通过摄像机指定的web插件转码辅助播放,如海康,大华摄像机;3、还有个猿大师播放器基于猿大师中间件提供的内嵌网页播放(没用过,不知道行不行,原本想用现在这个方法行不行的,若不行就用这个猿大师了的)

开始

:
node.js工具
jsmpeg.js文件
npm install rtsp2web

科普了解一下

  1. rtsp2web 是一个依赖 ffmpeg,能实时将传入的 rtsp 视频流转码成图像数据并通过 ws 推送到前端的智能工具。
  2. 前端页面借助 jsmpeg.js 就可以很轻松的实现播放
  3. 同时rtsp2web的特点还有:1、并发,支持同时播放多路视频2、合并同源,同时播放多个同一个rtsp视频源时,只会创建一个转码推流进程,不会创建多个。3、智能释放资源,智能检测当前没有使用的转码推流进程,将其关闭,并释放电脑资源。

使用

下载ffmpeg(链接: https://www.ffmpeg.org/download.html#build-windows

安装成功以后,你重新打开一个命令行终端,输入:ffmpeg -h,如果能输出 ffmpeg 的相关信息出来,则证明你的电脑安装 ffmpeg 成功。

使用rtsp2web

创建了一个vuecli(vue2)项目,名称不要起rtsp2web,与src文件夹同级
下创建一个serve文件夹

-|public
    |-favicon.ico
    |-index.html
-|src
-|serve
-|.gittignore
-.....  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

在serve下初始化和下载

npm init --yes
npm install rtsp2web  
  • 1
  • 2

在serve下创建index.js

//index.js
const RTSP2web = require('rtsp2web')

//服务端的端口号,端口号可以自定义
const port = 8033
new RTSP2web({
    port
)}  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

运行命令:node index.js

前端代码

在public的index.html中
其中jsmpeg.min.js通过src引入,可以用jsmpeg.js或者jsmpeg.min.js都行

<!DOCTYPE html>
<html lang="">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <link rel="icon" href="<%= BASE_URL %>favicon.ico">
    <!--v  jsmpeg.min.js文件用在这   v-->
    <script src="https://jsmpeg.com/jsmpeg.min.js" charset="utf-8"></script>    
    <title><%= htmlWebpackPlugin.options.title %></title>
  </head>
  <body>
    <noscript>
      <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
    </noscript>
    <div id="app"></div>
    <!-- built files will be auto injected -->
  </body>
  <script>
    var rtsp = 'rtsp://username:password@ip:port/live'
    window.onload = () => {
    //这里的port要与index.js的port保持一致
    new JSMpeg.Player("ws://localhost:8033/rtsp?url="+btoa(rtsp), {
       canvas: document.getElementById("canvas")
    })
  }
  </script>
</html>  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

#####在vue页面中用canvas中播放视频
如 在App.vue中这样用:

<template>
  <div id="app">
    <!-- <img alt="Vue logo" src="./assets/logo.png">
    <HelloWorld msg="Welcome to Your Vue.js App"/> -->
    <canvas id="canvas" style="width: 600px; height: 600px;"></canvas>
  </div>
</template>  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

问题

为什么node index.js之后没反应?
—检查端口号是否填写对应,index.js中的端口要与script里的端口保持一致
|
为什么长时间未显示图像?
—需要等待大概1-2分钟,就会显示画面。至于这么长时间未显示,小弟也不知道啊。。希望大佬指点。。

最后

完事了就,这是我历经千辛万苦找到的方法,弄这个vue中播放rtsp搞了好久,技术太拉了我,只能用这些小玩意来搞。原本打算用java或者python通过拉rtsp流解析成rtmp的,奈何能力不足,也懒得思考懒得搞懒得弄,所以摆烂了QAQ
若哪里有讲的不妥和使用不当的地方还请您告知一下,万分感谢大佬指点,小弟深表感谢<抱拳>
-----------------------------------------------------------------------------------------------------------

参考。1


  1. https://zhuanlan.zhihu.com/p/531899593 ↩︎
    蓝蓝设计建立了UI设计分享群,每天会分享国内外的一些优秀设计,如果有兴趣的话,可以进入一起成长学习,请加微信ban_lanlan,报下信息,蓝小助会请您入群。欢迎您加入噢~~
    希望得到建议咨询、商务合作,也请与我们联系01063334945。 

    分享此文一切功德,皆悉回向给文章原作者及众读者. 免责声明:蓝蓝设计尊重原作者,文章的版权归原作者。如涉及版权问题,请及时与我们取得联系,我们立即更正或删除。 

    蓝蓝设计www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计、BS界面设计 、 cs界面设计 、 ipad界面设计 、 包装设计 、 图标定制 、 用户体验 、交互设计、 网站建设 平面设计服务UI设计公司、界面设计公司、UI设计服务公司、数据可视化设计公司、UI交互设计公司、高端网站设计公司、UI咨询、用户体验公司、软件界面设计公司

视频的传输方式【转】

前端达人

概述

搜索“视频传输协议”,一般会搜出来RTP,RTSP,UDP等等。光看这些协议,可能有些人会觉得奇怪为什么要把udp也往上放一起,rtp不是可以基于udp?!同时,很多文章主要去讲解各个协议之间的差异,而没有从更为宏观的角度来考虑。本文将结合OSI的分层思路,将不同协议之间的关系都梳理清楚;同时也从视频传输与组网角度进行介绍。
再者,视频有很多封装格式,比如m3u8,mp4等;也有很多音视频编码格式,比如h264,h265等,那为何有这么多的封装格式类型和音视频编码格式类型呢?一方面是解决存储的问题;另一方面是支持不同播放器的解析;但更重要的是不同的传输协议可以支持的音视频编码格式有差异,这也是由于不同的应用场景下形成的历史原因。

1.流媒体

流媒体(streaming media),是指将一连串的媒体数据包从服务器端发送到客户端,可以实现边下边播,此技术使得数据包可以像流水一样发送。传统的方式需要在使用前下载整个文件,存储到本地后才能进行播放;而流媒体只允许下载一小部分(存在视频关键帧)就能进行播放。

流媒体技术不是一种单一的技术,它将网络技术、音视频技术还有终端缓存技术等有机地结合。也就是说,在网络上要实现流媒体技术,必须要先制作、发布、传输和播放等,这需要服务器端、终端以及网络都要能支持。当前很多的视频软件或者网站都是用到了这种技术。归结下来是:

  • 1.内容的产生。这里是指将视频源制作成为可以对外发布的视频格式,以及适合在网络上传播的分辨率和码率。这主要用到了视频的编解码技术。考虑的输出参数,如分辨率、码率、音视频编码格式、封装格式等都需要结合应用场景和传输方式统一考虑。

  • 2.对外发布。这里主要是指能够支撑服务器对外输出视频资源的技术,常见的有各种流媒体网络传输协议技术及其需要服务器端支撑的技术。这里的流媒体网络传输协议比如:

    • HLS
      服务端支持Adobe Flash media server,Nginx,vlc等等。
    • DASH
      服务器端支持Nginx等
    • RTMP
    • Adobe Flash 服务器,Nginx-rtmp
  • 3.组网和传输。
    这里的传输还得考虑一个概念,是服务器对外主动推数据,还是等待终端到服务器端拉数据,这是两个完全相反的处理方式。对于组播或者广播的组网方式,往往采用的是服务器主动对外推送数据;而对于单播来说主要是终端向服务器端主动拉数据。

    这里涉及到的IP组网方式中的传输类型有:广播、单播、组播。

    不管是什么类型的组网方式,在传输层就有UDP和TCP。下面也将从OSI等层面讲讲这些底层传输协议之间的关系。

  • 4.视频播放。这里主要是从终端侧角度说,在不同操作系统中能够进行播放视频的播放器,比如vlc等,不同的播放器支持对不同类型的视频数据进行播放。

2.TCP/IP、OSI与视频传输协议之间的关系

从图中也可以看到IP层(网络层)的上层是传输层,通过TCP和UDP等方式进行数据包的传输。
(PS:下图为网络中所找https://blog.csdn.net/yaopeng_2005/article/details/7064869)
在这里插入图片描述
结合上图,再补一个wiki上的互联网协议套组图,一看就更明白了。
在这里插入图片描述
从上面两个图中也可以很清楚地看到,TCP和UDP在接下去的内容有很重要的地位,这里也简单介绍下,深度知识请自行搜索。

  • 1)TCP(Transmission Control Protocol)传输控制协议
    是一种面向连接的、可靠的、基于字节流的传输层协议。也就是说,它在收发数据之前,必须先和对方建立可靠的连接。有兴趣地可以了解TCP的三次握手过程。当TCP检测到数据包丢失时,它将限制其数据速率使用率,因此也说TCP是靠谱的,但是对于实时类型的业务,可能不那么适合。
  • 2)UDP(User Datagram Protocol)用户数据报协议
    是一种简单的面向数据报的通信协议。UDP只提供数据的不可靠传递,它将数据发送出去后,就不保留备份,它仅仅在IP数据报的头部加入了复用和数据校验字段。由于不需要多长校验,UDP的速度比TCP快,但是有数据丢失风险,因此比较适用于实时性要求高的场景,比如实时语音或视频通话。广电网络场景中,以前多用UDP进行传输,而且是组播或广播的方式,这结合组网能够将流量成本较大地控制下来。
  • 3)IP层(Internet Protocol)
    IP是网络层的主要协议,将根据源主机和目的主机的地址进行数据传输。定义了寻址方法和数据报的封装结构。其最为复杂的就是寻址和路由了。寻址就是将IP地址分配给各个终端节点,并如何进行划分和组网。而路由主要是内部和外部网关协议,决定了怎么发送IP数据包。下面提到的组播和广播等,其实主要是针对IP多播来说的。
  • 4)在不同层之间的数据的术语称呼
    数据在TCP层称为流(Stream),数据分组称为分段(Segment)
    数据在IP层称为Datagram,数据分组称为分片(Fragment)
    在UDP中,分组称为Message

3.组播、单播和广播

  • 组播(multicast)
    又称为多点广播或群播,或多播,主要是指将信息同时传递给一组目的地址。消息在每个网络链路上只需传递一次,而且只有在链路分叉时,消息才会被复制,使用的效率是最高的。也正是因为这个原因,以前的广电网络中,针对直播多采用组播方式,流量的传输成本明显降低很多。

  • 单播:
    其实是组播的一种特殊方式,即常规的点到点信息传递。如果所有传输中是以单播的方式传递给多个接收方,必须向每个接收者都发送一份数据副本这么多。

  • 广播
    其实也算是组播的一种特殊方式,就是一对所有的通信方式,对每一台主机发出的信号都进行无条件复制并转发,所有的接收点都可以收到所有信息。

注意,组播一般指的是IP组播,常与RTP等音视频协议相结合。虽然组播的设计理念很好,但是它需要对网络内部的状态比单播要多得多。实际商用中,组播主要应用在较为简单的、只有单个源断的情况,如之前提到广电网络内部用到的组播方式,UDP组播。

以上是不同类型的IP组播方式,实际在采用中要结合具体情况进行调整。比如,如果非要使用广播,但是采用的场景不合适,也有可能产生广播风暴。

组播、广播、单播也介绍了基本的概念,但是他们与视频传输有什么关系呢?

文章上面也提到了,组播是从IP层面的传输策略,而所有的视频传输协议其数据包大部分都经过UDP和TCP,经由IP层进行传输到目的地。因此不同的IP传输策略与传输协议进行结合,就能够落地到具体的应用场景。

同时需要注意的是,采用组播方式可以通过设置网卡为混杂模式或为多播模式,具体也是根据网卡的特性进行差异处理。如果处理方式不当,比如设置成了广播,可能会导致在同网络下,你在播放视频,然后其他相同网络下接收端也将有相应的流量,而导致他们的对外服务网口的流量被占满。

4.视频传输协议

从下图中可以看到,标红色的就是大家经常说的视频传输协议。但是从图中可以看到他们其实是有基于的关系,比如HLS都是基于HTTP进行传输,而HTTP在传输层都是依赖tcp数据包,再经由ip层进行分发。
在这里插入图片描述

  • 1)UDP

    • 基于UDP传输的视频数据,比如udp://238.123.45.1:3001,在网络可达的情况下,即可进行播放。可以采用vlc等播放器进行播放。

    • UDP视频数据传输可以采用单播,组播或广播的方式,具体采用哪种方式根据具体的组网情况进行控制。

    • 上面也有提到过,广电网络中多采用组播的方式进行直播数据传输,这也是得益于广电网络的专网特性以及视频源输出可以控制到单一等特性。

    • UDP的组播大部分是采用MPEG TS流,广电网络中很多视频,其视频编码格式也大部分是mepg2

  • 2)RTP
    整个RTP协议包括RTP数据协议和RTP控制协议(RTCP)。此外,这里也将经常一起提的RTSP介绍下。

    • RTP(实时传输协议,Real-time Transport Protocol),是一种网络传输协议

    • RTP协议说明了传递音频和视频的标准数据包的格式。最早是作为多播协议的,后来主要应用在单播中。RTP是创建在UDP协议之上的,主要应用于流媒体、视频会议等系统业务上。

    • RTP为端到端的数据传输提供了时间信息和流同步,但不保证服务质量,而是由服务质量由RTCP。
      在RTP的数据包封装中,包含了时间戳、标记位、同步源标识等信息。

    • RTP从上层接收到流媒体的数据(如H264),封装成RTP数据包,并将其发往UDP端口中的偶数端口。

    • RTCP(实时传输控制协议,Real-time Transport Control Protocol或RTP Control Protocol)

    • RTP的姐妹协议。RTP使用的是偶数UDP端口,RTCP采用的是RTP下一个端口,也就是下一个奇数的端口。RTCP也是基于UDP进行传输的。

    • RTCP本身不做数据传输,主要与RTP协作,将视频媒体数据打包和发送,并定期在流媒体会话参与者之间传输控制数据,并为RTP提供QoS反馈,简单点说是主要保证音视频的同步。

    • RTCP接收到控制信息后,封装为RTCP控制包,并发往RTP端口下一个偶数端口。

    • RTSP(实时流协议,Real Time Streaming Protocol)
      RTSP是一种网络应用协议,主要来创建和控制流媒体服务器与终端之间的会话。控制类的请求主要走TCP协议。

    • 通过RTSP对流媒体数据进行控制和播放,比如进行播放、暂停、快进等操作,它定义了具体的控制消息、操作方法和状态码等。

    • 与RTP、RTCP配合,在广电网络内部主要应用在点播场景比较多,而直播主要走UDP组播。在互联网场景下,也有用于直播和点播的,但是相对来说使用较少。

    • 请求的url为:rtsp://testdomain/test.mp4/streamid=0

    • 需要服务器端和客户端都能够支持RTSP的控制。一般客户端采用vlc即可,而服务器端采用Darwin Streaming Server,ffmpeg等建立流媒体服务。

  • 3)RTMP(实时消息协议,Real-Time Messaging Protocol)
    包括RTMP、RTMPT等一系列的协议,Adobe为flash播放器和服务器之间音视频数据传输的协议。

    • RTMP
      1)主要基于TCP协议进行数据包传输,默认使用1935端口。
      2)服务器端采用Nginx,支持rtmp模块的即可支持对外rtmp视频数据服务。
      3)支持rtmp模块,可以支持直播rtmp输出,也能够支持hls访问。
      4)RTMP支持mp4,flv等封装格式的视频对外输出
    • RTMPS
      通过SSL加密的RTMP协议
    • RTMPE
      RTMPE是一个加密版本的RTMP,和RTMPS不同的是RTMPE不采用SSL加密,RTMPE加密快于SSL,并且不需要认证管理
    • RTMPT
      采用HTTP封装以穿透防火墙,通常用80和443端口。
    • RTMFP
      使用UDP进行数据传输

4)HTTP
而基于HTTP协议的就更多了,如上图。如果服务器部署了流媒体的服务,如Nginx等,就可以对外提供视频播放服务了。

这里也需要说明,视频的播放一般分为点播和直播,有些协议作为直播的传输协议反而是更好的,比如RTMP,时延就比较低,但RTMP做CDN成本相对较高。CDN支持很好的HTTP如果能支持直播,当前也有很多协议能支持通过HTTP的方式实现直播流媒体。

5.自适应流媒体

自适性流媒体(adaptive bitrate streaming,ABS)也叫码流自适应,是流媒体服务器准备各种码流的视频流,所有的视频码流都是相同时段完全统一图像的音视频数据,客户端根据网络情况和CPU使用情况等进行动态调整。

主要有MPEG-DASH、HLS、HDS、MSS等技术方案,这几个也是上图中最上层的流媒体传输协议技术。通过这些传输协议封装的视频源,可以支持有多种码率,并支持播放器客户端在播放时,根据带宽情况自动调整码率以适应用户的最佳观看效果——不卡顿,不重新加载等。

  • 1) DASH(MPEG-DASH)
    MPEG-DASH是基于HTTP的自适应码流方案中唯一国际标准,它采用TCP传输协议。
  • 2)HLS
    Apple提出的,将.m3u8作为索引文件,分片格式为ts,支持直播和时移。
  • 3)HDS
    采用支持RTMP和HTTP协议,HTTP协议类似于HLS,也可以叫渐进式下载。
  • 4)MSS
    是微软提出的,文件切片格式为mp4,索引文件为ism、ismc,也支持直播和时移。

这里也仅仅对码流自适应技术做了简单介绍,由于现在这种技术应用相当广泛,后面将详细介绍这种技术。

【说明】
文章转自,华为云社区,作者Higeeon,相关版权解释权归原作者所有。https://bbs.huaweicloud.com/blogs/fed3df04b1e011e9b759fa163e330718





蓝蓝设计建立了UI设计分享群,每天会分享国内外的一些优秀设计,如果有兴趣的话,可以进入一起成长学习,请加微信ban_lanlan,报下信息,蓝小助会请您入群。欢迎您加入噢~~

希望得到建议咨询、商务合作,也请与我们联系01063334945。 



分享此文一切功德,皆悉回向给文章原作者及众读者. 免责声明:蓝蓝设计尊重原作者,文章的版权归原作者。如涉及版权问题,请及时与我们取得联系,我们立即更正或删除。 



蓝蓝设计www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计、BS界面设计 、 cs界面设计 、 ipad界面设计 、 包装设计 、 图标定制 、 用户体验 、交互设计、 网站建设 平面设计服务UI设计公司、界面设计公司、UI设计服务公司、数据可视化设计公司、UI交互设计公司、高端网站设计公司、UI咨询、用户体验公司、软件界面设计公司

JavaScript核心技术之JSON详解

前端达人

JSON是什么?

JSON(JavaScript Object Notation, JS对象简谱)是一种轻量级的数据交换格式。它基于 ECMAScript(European Computer Manufacturers Association, 欧洲计算机协会制定的js规范)的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。 

JSON源自于JavaScript,是一种轻量级(Light-Meight)、基于文本的(Text-Based)、可读的(Human-Readable)格式。

在现在的开发中,能够进行数据交换格式的,包括两个JSON   XML。

JSON是存储和交换文本信息的语法,类似 XML,JSON比 XML更小、更快,更易解析。

 那么,简而言之,对JSON的说明总结如下:

  • JSON是独立于任何编程语言的数据格式
  • 是一种用于存储和传输数据的轻量级格式
  • 语法是自描述的,便于人类阅读和理解

JSON语法

基本语法:

  • 数组(Array)用方括号 "[]" 表示
  • 对象(0bject)用大括号 "{}" 表示
  • 名称 / 值 对(name/value)组合成数组和对象
  • 名称( name )置于双引号中,值(value)有字符串、数值、布尔值、null、对象和数组
  • 并列的数据之间用逗号 "," 分隔
  • 名称/值对包括字段名称(在双引号中),后面写一个冒号,然后是值

需要注意的是:

JSON不支持注释。向 JSON添加注释无效

JSON文件的文件类型是 .json

JSON文本的 MIME 类型是 application/json

获取JSON数据

 json是以对象的形式存在的,直接获取JSON数据可通过如下方法:

1. json对象.键名

2. json对象["键名"]

3. 数组对象[索引]

4. 遍历 

代码示例:


  1. //定义基本格式
  2. var person = { name: "张三", age: 23, gender: true };
  3. var persons = [
  4. { name: "张三", age: 23, gender: true },
  5. { name: "李四", age: 24, gender: true },
  6. { name: "王五", age: 25, gender: false },
  7. ];
  8. //获取person对象中所有的键和值
  9. //for in 循环
  10. /* for(var key in person){
  11. //这样的方式获取不行。因为相当于 person."name"
  12. //alert(key + ":" + person.key);
  13. alert(key+":"+person[key]);
  14. }*/
  15. //获取persons中的所有值
  16. for (var i = 0; i < persons.length; i++) {
  17. var p = persons[i];
  18. for (var key in p) {
  19. console.log(key + ":" + p[key]);
  20. }
  21. }

 输出结果为:

 JSON 解析与序列化(在JavaScript中)

先在控制台中打印一下JSON对象,看看有什么,如图:

 显而易见,在JavaScript中JSON对象仅有两个方法:parse和stringify。后面会详细介绍一下这两个方法

序列化的概念:序列化是将对象转化为字节序列的过程。对象序列化后可以在网络上传输,或者保存到硬盘上。

将对象序列化成json字符串: JSON.stringify(json对象);

反序列化:将json字符串反序列化为对象:   JSON.parse(str)

JSON.parse

API介绍:用来解析 JSON字符串,构造由字符串描述的 JavaScript 值或对象,传入的字符串不符合 JSON规范会报错

语法:

JSON.parse(str, reviver);
  • str:要解析的 JSON字符串
  • reviver:可选的函数 function(key,value),该函数的第一个参数和第二个参数分别代表键值对的键和值,并可以对值进行转换(函数返回值当做处理后的value)

代码示例:


  1. // JSON.parse() 解析JSON字符串, 将JSON转换为对象
  2. let json = '{"name": ["js", "webpack"], "age": 22, "gridFriend": "ljj"}';
  3. console.log(JSON.parse(json));
  4. // {name: Array(2), age: 22, gridFriend: 'ljj'}
  5. // 第二个参数是一个函数,key和value代表每个key/value对
  6. let result = JSON.parse(json, (key, value) => {
  7. if (key == "age") {
  8. return `年龄:${value}`;
  9. }
  10. return value;
  11. });
  12. console.log(result);
  13. //{name: Array(2), age: '年龄:22', gridFriend: 'ljj'}

 JSON.stringify

API介绍:将一个 JavaScript 对象或值转换为 JSON字符串

如果指定了一个 replacer 函数,则可以选择性地替换值,或者指定的 replacer 是数组,则可选择性地仅包含数组指定的属性

语法:

JSON.stringify(value, replacer, space)

value:将要序列化成 一个 JSON 字符串的值

replacer:

  • 如果该参数是一个函数,则在序列化过程中,被序列化的值的每个属性都会经过该函数的转换和处理
  • 如果该参数是一个数组,则只有包含在这个数组中的属性名才会被序列化到最终的 JSON 字符串中
  • 如果该参数为 null 或者未提供,则对象所有的属性都会被序列化

space:指定缩进用的空白字符串,用于美化输出

  • 如果参数是个数字,它代表有多少的空格;上限为10。该值若小于1,则意味着没有空格
  • 如果该参数为字符串(当字符串长度超过10个字母,取其前10个字母),该字符串将被作为空格
  • 如果该参数没有提供(或者为 null),将没有空格

代码示例:


  1. let obj = {
  2. name: "jsx",
  3. age: 22,
  4. lesson: ["html", "css", "js"],
  5. };
  6. let json = JSON.stringify(obj);
  7. console.log(json);
  8. // {"name":"jsx","age":22,"lesson":["html","css","js"]}
  9. // 第二个参数replacer 为函数时,被序列化的值得属性都会经过该函数转换处理
  10. function replacer(key, value) {
  11. if (typeof value === "string") {
  12. return undefined;
  13. }
  14. return value;
  15. }
  16. let result = JSON.stringify(obj, replacer);
  17. console.log(result);
  18. // {"age":22,"lesson":[null,null,null]}
  19. // 当replacer参数为数组,数组的值代表将被序列化成 JSON 字符串的属性名
  20. let result1 = JSON.stringify(obj, ["name", "lesson"]);
  21. // 只保留 “name” 和 “lesson” 属性值
  22. console.log(result1);
  23. // {"name":"jsx","lesson":["html","css","js"]}
  24. // 第三个参数spcae,用来控制结果字符串里面的间距
  25. let result2 = JSON.stringify(obj, null, 4);
  26. console.log(result2);
  27. /*{
  28. "name": "jsx",
  29. "age": 22,
  30. "lesson": [
  31. "html",
  32. "css",
  33. "js"
  34. ]
  35. }*/

 注意:如果replacer是一个函数,则该函数会进行深处理,即如果键值对的值也是一个数组,则也会执行该函数

JSON.stringify()原理

  • 转换值如果有 toJSON() 方法,该方法定义什么值将被序列化
  • 非数组对象的属性不能保证以特定的顺序出现在序列化后的字符串中
  • 布尔值、数字、字符串的包装对象在序列化过程中会自动转换成对应的原始值,undefined、任意的函数以及 symbol 值,在序列化过程中会被忽略(出现在非数组对象的属性值中时)或者被转换成 null(出现在数组中时)。函数、undefined 被单独转换时,会返回 undefined,如JSON.stringify(function(){}) or JSON.stringify(undefined)
  • 对包含循环引用的对象(对象之间相互引用,形成无限循环)执行此方法,会抛出错误
  • 所有以 symbol 为属性键的属性都会被完全忽略掉,即便 replacer 参数中强制指定包含了它们
  • Date 日期调用了 toJSON() 将其转换为了 string 字符串(同Date.toISOString()),因此会被当做字符串处理
  • NaN 和 Infinity 格式的数值及 null 都会被当做 null
  • 其他类型的对象,包括 Map/Set/WeakMap/WeakSet,仅会序列化可枚举的属性


蓝蓝设计建立了UI设计分享群,每天会分享国内外的一些优秀设计,如果有兴趣的话,可以进入一起成长学习,请加微信ban_lanlan,报下信息,蓝小助会请您入群。欢迎您加入噢~~
希望得到建议咨询、商务合作,也请与我们联系01063334945。 

分享此文一切功德,皆悉回向给文章原作者及众读者. 免责声明:蓝蓝设计尊重原作者,文章的版权归原作者。如涉及版权问题,请及时与我们取得联系,我们立即更正或删除。 

蓝蓝设计www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计、BS界面设计 、 cs界面设计 、 ipad界面设计 、 包装设计 、 图标定制 、 用户体验 、交互设计、 网站建设 平面设计服务UI设计公司、界面设计公司、UI设计服务公司、数据可视化设计公司、UI交互设计公司、高端网站设计公司、UI咨询、用户体验公司、软件界面设计公司

get请求和post请求的区别(全面讲解)

前端达人

1.get请求一般是去取获取数据(其实也可以提交,但常见的是获取数据);
post请求一般是去提交数据。

2.get因为参数会放在url中,所以隐私性,安全性较差,请求的数据长度是有限制的,
不同的浏览器和服务器不同,一般限制在 2~8K 之间,更加常见的是 1k 以内;
post请求是没有的长度限制,请求数据是放在body中;

3.get请求刷新服务器或者回退没有影响,post请求回退时会重新提交数据请求。

4.get请求可以被缓存,post请求不会被缓存。

5.get请求会被保存在浏览器历史记录当中,post不会。get请求可以被收藏为书签,因为参数就是url中,但post不能。它的参数不在url中。

6.get请求只能进行url编码(appliacation-x-www-form-urlencoded),post请求支持多种(multipart/form-data等)。

深入理解
1…GET 和 POST都是http请求方式, 底层都是 TCP/IP协议;通常GET 产生一个 TCP 数据包;POST 产生两个 TCP 数据包(但firefox是发送一个数据包),

2.对于 GET 方式的请求,浏览器会把 http header 和 data 一并发送出去,服务器响应 200
(返回数据)表示成功;

而对于 POST,浏览器先发送 header,服务器响应 100, 浏览器再继续发送 data,服
务器响应 200 (返回数据)。





蓝蓝设计建立了UI设计分享群,每天会分享国内外的一些优秀设计,如果有兴趣的话,可以进入一起成长学习,请加微信ban_lanlan,报下信息,蓝小助会请您入群。欢迎您加入噢~~

希望得到建议咨询、商务合作,也请与我们联系01063334945。 



分享此文一切功德,皆悉回向给文章原作者及众读者. 免责声明:蓝蓝设计尊重原作者,文章的版权归原作者。如涉及版权问题,请及时与我们取得联系,我们立即更正或删除。 



蓝蓝设计www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计、BS界面设计 、 cs界面设计 、 ipad界面设计 、 包装设计 、 图标定制 、 用户体验 、交互设计、 网站建设 平面设计服务UI设计公司、界面设计公司、UI设计服务公司、数据可视化设计公司、UI交互设计公司、高端网站设计公司、UI咨询、用户体验公司、软件界面设计公司

【uni-app】响应式单位rpx

前端达人

单位

rpx是响应式px
rpx是一种根据屏幕宽度自适应的动态单位。以750宽的屏幕为基准,750rpx正好是屏幕的宽度。屏幕变宽,rpx实际显示效果会等比放大,但在App端和h5端,屏幕宽度达到960px时,默认将按照375px的屏幕宽度进行计算。在开发移动端项目时选择rpx作为尺寸单位。
uni-app在App端,H5端和小程序都支持rpx,并且可以配置不同屏幕宽度的计算方式。

页面元素在uni-app的宽度计算公式如下:
750 * 元素在设计稿中的宽度 / 设计稿基准宽度

举例说明:

  1. 若设计稿宽度为750px,元素A在设计稿上的宽度为100rpx, 那么元素A在uni-app中的宽度应该设计为750 * 100/750,即100rpx
  2. 若设计稿宽度为640px,元素A在设计稿上的宽度为100rpx, 那么元素A在uni-app中的宽度应该设计为750 * 100/640,即117rpx
  3. 若设计稿宽度为375px,元素A在设计稿上的宽度为200rpx, 那么元素A在uni-app中的宽度应该设计为750 * 200/375,即117rpx

但是要注意的是

  1. 不要对响应式单位依赖太严重了,比如组件高度或字体大小也使用rpx。只有当你需要某元素的单位要根据屏幕宽度大小变化时,才需要rpx这类动态宽度单位。
  2. 一般情况下高度和字体大小是不应该根据屏幕宽度变化的,除非你的字体大小想根据屏幕宽度变化。
  3. rpx不支持动态横竖屏切换计算,使用rpx建议锁定屏幕方向

拓展:在设置文件mainfest.json里开启px转rpx(默认关闭),所有的px可一键转换为rpx

“transformPx”:false  
        
  • 1

rpx直接支持动态绑定

<view class="test" :style="{width:winWidth + 'rpx;'}"></view> 
        
 
        
  • 1


蓝蓝设计建立了UI设计分享群,每天会分享国内外的一些优秀设计,如果有兴趣的话,可以进入一起成长学习,请加微信ban_lanlan,报下信息,蓝小助会请您入群。欢迎您加入噢~~
希望得到建议咨询、商务合作,也请与我们联系01063334945。 

分享此文一切功德,皆悉回向给文章原作者及众读者. 免责声明:蓝蓝设计尊重原作者,文章的版权归原作者。如涉及版权问题,请及时与我们取得联系,我们立即更正或删除。 

蓝蓝设计www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计、BS界面设计 、 cs界面设计 、 ipad界面设计 、 包装设计 、 图标定制 、 用户体验 、交互设计、 网站建设 平面设计服务UI设计公司、界面设计公司、UI设计服务公司、数据可视化设计公司、UI交互设计公司、高端网站设计公司、UI咨询、用户体验公司、软件界面设计公司

Vue跨域解决方法

前端达人

vue项目中,前端与后台进行数据请求或者提交的时候,如果后台没有设置跨域,前端本地调试代码的时候就会报“No 'Access-Control-Allow-Origin' header is present on the requested resource.” 这种跨域错误。

要想本地正常的调试,解决的办法有三个

一、后台更改header

header('Access-Control-Allow-Origin:*');//允许所有来源访问
header('Access-Control-Allow-Method:POST,GET');//允许访问的方式

这样就可以跨域请求数据了

二、使用JQuery提供的jsonp (注:vue中引入jquery,自行百度)

methods: {
getData () {
var self = this
$.ajax({
url: 'http://f.apiplus.cn/bj11x5.json',
type: 'GET',
dataType: 'JSONP',
success: function (res) {
self.data = res.data.slice(0, 3)
self.opencode = res.data[0].opencode.split(',')
}
})
}
}

通过这种方法也可以解决跨域的问题。

三、使用http-proxy-middleware 代理解决(项目使用vue-cli脚手架搭建)

例如请求的url:“/business/remind/user”
1、打开vue.config.js.js,在proxy中添写如下代码:

// 运行配置
devServer: {
port: '9527', //代理端口
open: false, //项目启动时是否自动打开浏览器,我这里设置为false,不打开,true表示打开
proxy: {
'/api': {
target: process.env.VUE_APP_HTTP_URL,
changeOrigin: true, //是否跨域
pathRewrite: { //重写路径
'^/api': '/' // 或 者 'http://localhost:8080/api'
}
// 既然我们设置了代理,则所有请求url都已写成/api/xxx/xxx,那请求如何知道我们到底请求的是哪个服务器的数据呢
// 因此这里的意义在于, 以 /api开头的url请求,代理都会知道实际上应该请求那里,
// ‘我是服务器/api’,后面的/api根据实际请求地址决定,即我的请求url:/api/test/test,被代理后请求的则是
// https://我是服务器/api/test/test
}
}
},

附带vue.config.js下的代码

const chalk = require('chalk')
const path = require('path');
function resolve (dir) {
return path.join(__dirname, dir)

}
module.exports = {
// 没有书写outputDir属性 默认'dist' 对应dev.assetsSubDirectory
outputDir: 'dist',
// https://vuejs.org/v2/guide/installation.html#Runtime-Compiler-vs-Runtime-only
// compiler: false,
//在vue-cli.3.3版本后 baseUrl被废除了,因此这边要写成 publicPath ( 资源地址 )
publicPath: process.env.NODE_ENV === 'production' ? process.env.VUE_APP_PUBLICPATH : '/' ,
// css相关配置
css: {
// 是否使用css分离插件 ExtractTextPlugin
extract: true,
// 开启 CSS source maps?
sourceMap: false,
// css预设器配置项
loaderOptions: {}
// 启用 CSS modules for all css / pre-processor files.
// modules: false
},
// 运行配置
devServer: {
port: '8222', //代理端口
open: false, //项目启动时是否自动打开浏览器,我这里设置为false,不打开,true表示打开
proxy: {
'/api': {
target: process.env.VUE_APP_HTTP_URL,
changeOrigin: true, //是否跨域
pathRewrite: { //重写路径
'^/api': '/' // 或 者 'http://localhost:8080/api'
}
// 既然我们设置了代理,则所有请求url都已写成/api/xxx/xxx,那请求如何知道我们到底请求的是哪个服务器的数据呢
// 因此这里的意义在于, 以 /api开头的url请求,代理都会知道实际上应该请求那里,
// ‘我是服务器/api’,后面的/api根据实际请求地址决定,即我的请求url:/api/test/test,被代理后请求的则是
// https://我是服务器/api/test/test
}
}
},
chainWebpack: config => {
// 提示输出的哪个地址
console.log(chalk.blueBright('\n\n running ' + process.env.VUE_APP_PROJ_NAME + ' : ') +
chalk.yellowBright(process.env.VUE_APP_HTTP_URL + ' please wait... \n'));
// 判断不同环境 做相应处理
if(process.env.NODE_ENV === 'production') {
// 测试生产环境, 不压缩js代码
if (process.env.VUE_APP_TITLE === 'alpha') {
config.optimization.minimize(false)
}
}
//set第一个参数:设置的别名,第二个参数:设置的路径
config.resolve.alias
.set('@',resolve('./src'))
.set('components',resolve('./src/components'))
.set('assets',resolve('./src/assets'))
.set('views',resolve('./src/views'))
.set('network',resolve('./src/network'))
//注意 store 和 router 没必要配置

config.plugin('html')
.tap(args => {
args[0].title = '公募综合业务平台'
return args
})
}
}





蓝蓝设计建立了UI设计分享群,每天会分享国内外的一些优秀设计,如果有兴趣的话,可以进入一起成长学习,请加微信ban_lanlan,报下信息,蓝小助会请您入群。欢迎您加入噢~~

希望得到建议咨询、商务合作,也请与我们联系01063334945。 



分享此文一切功德,皆悉回向给文章原作者及众读者. 免责声明:蓝蓝设计尊重原作者,文章的版权归原作者。如涉及版权问题,请及时与我们取得联系,我们立即更正或删除。 



蓝蓝设计www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计、BS界面设计 、 cs界面设计 、 ipad界面设计 、 包装设计 、 图标定制 、 用户体验 、交互设计、 网站建设 平面设计服务UI设计公司、界面设计公司、UI设计服务公司、数据可视化设计公司、UI交互设计公司、高端网站设计公司、UI咨询、用户体验公司、软件界面设计公司

日历

链接

blogger

蓝蓝 http://www.lanlanwork.com

存档