Mock.js随机字符串方法string的bug记录

该博客讲述了在使用Mock.js库生成随机密码时遇到的问题,即生成的字符串包含美元符号($)导致的正则表达式错误。作者深入源码,发现问题出在`result.replace(ph, phed)`这行,由于$在正则中有特殊含义。解决方案是先将$替换为其他字符,如空格,然后在替换完成后移除空格。修正后的代码有效地解决了这个问题,确保了随机字符串生成的正确性。

在写一个随机生成密码的过程中,引用到了Mock.js这个库,测试过程发现了string方法测试的数据一多就会出现bug,这里把执行的@string(8,9)这个随机的方法也显示到随机的结果里面,如下:

后来查看源码发现是由于正则表达式替换的时候,$符号的特殊含义导致的,出现bug的方法代码为:

string: function(options) {
	        var result = '',
	            i, placeholders, ph, phed;
	        if (options.template.length) {

	            //  'foo': '★',
	            /* jshint -W041 */
	            if (options.rule.count == undefined) {
	                result += options.template
	            }

	            // 'star|1-5': '★',
	            for (i = 0; i < options.rule.count; i++) {
	                result += options.template
	            }
	            // 'email|1-10': '@EMAIL, ',
	            placeholders = result.match(Constant.RE_PLACEHOLDER) || [] // A-Z_0-9 > \w_
	            for (i = 0; i < placeholders.length; i++) {
	                ph = placeholders[i]

	                // 遇到转义斜杠,不需要解析占位符
	                if (/^\\/.test(ph)) {
	                    placeholders.splice(i--, 1)
	                    continue
	                }
	                phed = Handler.placeholder(ph, options.context.currentContext, options.context.templateCurrentContext, options)

	                // 只有一个占位符,并且没有其他字符
	                if (placeholders.length === 1 && ph === result && typeof phed !== typeof result) { // 
	                    result = phed
	                    break

	                    if (Util.isNumeric(phed)) {
	                        result = parseFloat(phed, 10)
	                        break
	                    }
	                    if (/^(true|false)$/.test(phed)) {
	                        result = phed === 'true' ? true :
	                            phed === 'false' ? false :
	                            phed // 已经是布尔值
	                        break
	                    }
	                }
	                result = result.replace(ph, phed);
	            }

	        } else {
	            // 'ASCII|1-10': '',
	            // 'ASCII': '',
	            result = options.rule.range ? Random.string(options.rule.count) : options.template
	        }
			return result;
	    }

主要是下面这一句导致的

 result = result.replace(ph, phed);

原因是$符号有以下特殊含义,当生成的字符串包含如下组合的字符串,就会出现问题:

 整改后的代码如下:

string: function(options) {
	        var result = '',
	            i, placeholders, ph, phed;
	        if (options.template.length) {

	            //  'foo': '★',
	            /* jshint -W041 */
	            if (options.rule.count == undefined) {
	                result += options.template
	            }

	            // 'star|1-5': '★',
	            for (i = 0; i < options.rule.count; i++) {
	                result += options.template
	            }
	            // 'email|1-10': '@EMAIL, ',
	            placeholders = result.match(Constant.RE_PLACEHOLDER) || [] // A-Z_0-9 > \w_
	            for (i = 0; i < placeholders.length; i++) {
	                ph = placeholders[i]

	                // 遇到转义斜杠,不需要解析占位符
	                if (/^\\/.test(ph)) {
	                    placeholders.splice(i--, 1)
	                    continue
	                }
	                phed = Handler.placeholder(ph, options.context.currentContext, options.context.templateCurrentContext, options)
					if(phed.indexOf('$')>-1){
						phed=phed.replace(/\$/g,'$ ');
					}
	                // 只有一个占位符,并且没有其他字符
	                if (placeholders.length === 1 && ph === result && typeof phed !== typeof result) { // 
	                    result = phed
	                    break

	                    if (Util.isNumeric(phed)) {
	                        result = parseFloat(phed, 10)
	                        break
	                    }
	                    if (/^(true|false)$/.test(phed)) {
	                        result = phed === 'true' ? true :
	                            phed === 'false' ? false :
	                            phed // 已经是布尔值
	                        break
	                    }
	                }
	                result = result.replace(ph, phed);
	            }

	        } else {
	            // 'ASCII|1-10': '',
	            // 'ASCII': '',
	            result = options.rule.range ? Random.string(options.rule.count) : options.template
	        }
	        return  result.indexOf(' ')>-1?result.replace(/ /g,''):result;
	    }

主要是改了这两个地方:

					if(phed.indexOf('$')>-1){
						phed=phed.replace(/\$/g,'$ ');
					}

return  result.indexOf(' ')>-1?result.replace(/ /g,''):result;

思路如下:

  1. 替换前把$符号的组合拆掉,我是填充了个空格来处理;
  2. 替换完后,再把空格处理掉就行了
<think>首先,用户的问题是:“我想了解如何使用mock.js随机生成图片 请问使用mock.js随机生成图片的方法”。我需要根据提供的引用信息来回答。 回顾引用内容: - 引用[1]:介绍了 Mock.mock 的基本用法,用于生成模拟数据。 - 引用[2]:展示了如何结合 AntDesign 和 mockjs 随机生成图片,使用七牛云存储图片,并通过随机整数访问。示例中使用 `'fileList|1-10': [{ url: 'http://xxxxx.xxx.clouddn.com/@name', ... }]`。 - 引用[3]:展示了使用 mockjs 生成随机数据的示例,包括 `'img': '@image()'` 用于随机图片。 - 引用[4]:提到 mock.js 使用,但主要是打印数据,没有特别关于图片的新信息。 - 引用[5]:详细解释了如何生成在线图片 URL,使用 `Random.image()` 方法,并给出了参数示例。 用户的核心需求是“如何使用mock.js随机生成图片”,所以我需要总结这些方法。 关键方法: 1. **使用 `@image()` 占位符**:在 mockjs 模板中,使用 `'img': '@image()'` 来生成随机图片 URL。这默认生成一个图片 URL,如 `http://dummyimage.com/...`。 2. **自定义图片 URL**:如引用[2]所示,可以构造 URL 如 `'url': 'http://xxxxx.xxx.clouddn.com/@name'`,其中 `@name` 是一个随机字符串或数字。 3. **使用 `Random.image()` 函数**:如引用[5]所示,`Random.image()` 可以生成图片 URL,并接受参数如大小、背景色、前景色、格式和文本。 从引用[5],`Random.image()` 的参数: - `size`:图片尺寸,如 '200x100' - `background`:背景颜色,如 '#FF6600' - `foreground`:前景颜色,如 '#FFF' - `format`:图片格式,如 'png' - `text`:图片上的文本,如 'Mock.js' 在 mockjs 中,`Random` 是全局对象,可以在模板中使用。 回答结构: - 保持清晰:逐步解释如何使用 mock.js 随机生成图片。 - 使用中文:因为系统指令要求中文回答。 - 格式要求:行内数学表达式用 `$...$`,独立公式用 `$$...$$`,但这个问题可能不涉及数学公式,所以可能不需要。 - 添加引用标识:在引用信息末尾添加 [^n]。 - 最后生成相关问题。 步骤: 1. **介绍基本方法**:使用 `@image()` 占位符。 2. **详细方法**:使用 `Random.image()` 函数,解释参数。 3. **示例代码**:提供简单示例来演示。 4. **结合其他引用**:提到如何自定义 URL 如引用[2]。 5. **总结**。 确保回答真实可靠,基于引用。 相关问题: - 生成 2-3 个相关问题,如优化图片生成、结合前端框架等。 最终回答: - 开头直接回答问题。 - 中段详细说明。 - 结尾添加相关问题。 </think> ### 如何使用 Mock.js 随机生成图片 Mock.js 是一个强大的数据模拟库,可轻松生成随机图片 URL。以下方法基于引用内容,逐步解释如何实现。 #### 1. **使用 `@image()` 占位符(简单方法)** - 在 Mock.js 模板中,`@image()` 是一个内置占位符,用于生成随机图片 URL。它会返回一个类似 `http://dummyimage.com/尺寸/背景色/前景色/格式/文本` 的 URL。 - **示例代码**: ```javascript const Mock = require('mockjs'); const data = Mock.mock({ 'list|5': [ // 生成5个对象组成的数组 { id: '@id', // 随机ID imgUrl: '@image()' // 随机图片URL,如 http://dummyimage.com/200x100 } ] }); console.log(data); ``` - 运行后,`imgUrl` 会输出随机图片链接,默认尺寸为 `200x100`,背景和前景色随机[^3][^5]。 - **优点**:简单快捷,无需额外配置。 #### 2. **使用 `Random.image()` 函数(自定义方法)** - `Random.image()` 提供更精细的控制,允许指定尺寸、颜色、格式和文本。参数顺序为: - `size`:图片尺寸(如 `'200x100'`)。 - `background`:背景色(十六进制代码,如 `'#FF6600'`)。 - `foreground`:前景(文本)颜色(如 `'#FFF'`)。 - `format`:图片格式(如 `'png'` 或 `'jpg'`)。 - `text`:图片上显示的文本(如 `'Mock.js'`)。 - **示例代码**: ```javascript const Mock = require('mockjs'); const data = Mock.mock({ 'image|3': [ // 生成3个图片对象 { url: Mock.Random.image('300x200', '#4A7BF7', '#FFF', 'png', 'Hello') // 自定义参数 } ] }); console.log(data); ``` - 输出示例:`url: "http://dummyimage.com/300x200/4A7BF7/FFF.png&text=Hello"`。 - **技巧**: - 忽略参数时使用 `null` 或省略,如 `Mock.Random.image('200x100', null, '#FFF')`。 - 结合其他占位符,如 `Mock.Random.image('@integer(100,500)x@integer(100,500)')` 生成动态尺寸。 #### 3. **结合自定义图片源(高级方法)** - 如引用[2]所示,你可以使用第三方服务(如七牛云)存储图片库,然后通过随机索引生成 URL。 - **步骤**: 1. 上传图片到云存储(如七牛云),文件名用数字编号(如 `1.jpg`, `2.jpg`)。 2.Mock.js 中,用 `@integer` 生成随机索引,拼接 URL。 - **示例代码**: ```javascript const Mock = require('mockjs'); const data = Mock.mock({ 'fileList|1-5': [ // 生成1-5个文件对象 { name: '图片', url: `http://your-cloud-domain.com/${Mock.Random.integer(1, 1000)}.jpg` // 随机访问1-1000编号的图片 } ] }); console.log(data); ``` - 此方法适合需要真实图片的场景,但需预先准备图库[^2]。 #### 注意事项 - **依赖安装**:确保已安装 Mock.js(`npm install mockjs`)。 - **默认服务**:`@image()` 和 `Random.image()` 基于 `dummyimage.com`,可能需要网络访问。 - **性能**:生成的是 URL 字符串,并非实际图片文件,适用于前端模拟数据[^1][^3]。 通过以上方法,你可以灵活生成随机图片数据用于开发测试。如需更多示例,参考 Mock.js 官方文档[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值