ASP.NET Boilerplate 学习 AspNet Core2 浏览器缓存使用 c#基础,单线程,跨线程访问和线程带参数 wpf 禁用启用webbroswer右键菜单 EF Core 2.0使用MsSql/MySql实现DB First和Code First ASP.NET Core部署到Windows IIS QRCode.js:使用 JavaScript 生成
ASP.NET Boilerplate 学习
1、在http://www.aspnetboilerplate.com/Templates 网站下载ABP模版

2、解压后打开解决方案,解决方案目录:

3、在AbpTest.Web.Host项目的appsettings.json中配置数据库连接字符串


新建名为AbpTestDb的空白数据库,在NuGet包管理控制台 执行 Update-Database 命令,初始化数据库

4、运行应用程序将看到Swagger生成的API接口页面

AspNet Core2 浏览器缓存使用
Core2中使用Microsoft.AspNetCore.Mvc下的ResponseCacheAttribute特性来控制Http Get请求的缓存
原理是设置http请求 响应头的Cache-control来告诉浏览器如何进行客户端缓存

1、在Startup的ConfigureServices方法里面设置一个CacheProfiles,Duration属性定义浏览器缓存的秒数,CacheProfiles一个通用的缓存配置项
services.AddMvc(option =>
{
/*客户端缓存*/
option.CacheProfiles.Add("default", new Microsoft.AspNetCore.Mvc.CacheProfile
{
Duration = 600 /*10分钟*/
});
});
2、在需要缓存的Action上面添加ResponseCacheAttribute特性,CacheProfileName 的值使用服务配置的名称,该Action将使用配置项进行缓存
[ResponseCache(CacheProfileName = "default")]
也可以在Action 上赋予 Duration 值,指定浏览器缓存的时间
查看ResponseCacheAttribute中的代码
public unsafe IFilterMetadata CreateInstance(IServiceProvider serviceProvider)
{
//IL_0000: Unknown result type (might be due to invalid IL)
//IL_0008: Unknown result type (might be due to invalid IL)
//IL_000e: Unknown result type (might be due to invalid IL)
//IL_0025: Unknown result type (might be due to invalid IL)
//IL_0032: Expected Ref, but got Unknown
//IL_0046: Unknown result type (might be due to invalid IL)
if (serviceProvider == (IServiceProvider)0)
{
throw new ArgumentNullException("serviceProvider");
}
IOptions<MvcOptions> requiredService = serviceProvider.GetRequiredService<IOptions<MvcOptions>>();
CacheProfile cacheProfile = null;
if (this.CacheProfileName != null)
{
((IDictionary)(?)requiredService.Value.CacheProfiles).TryGetValue((!0)this.CacheProfileName, ref *(!1*)(&cacheProfile));
if (cacheProfile == null)
{
throw new InvalidOperationException(Resources.FormatCacheProfileNotFound(this.CacheProfileName));
}
}
this._duration = (this._duration ?? ((cacheProfile != null) ? cacheProfile.Duration : null));
this._noStore = (this._noStore ?? ((cacheProfile != null) ? cacheProfile.NoStore : null));
this._location = (this._location ?? ((cacheProfile != null) ? cacheProfile.Location : null));
this.VaryByHeader = (this.VaryByHeader ?? ((cacheProfile != null) ? cacheProfile.VaryByHeader : null));
this.VaryByQueryKeys = (this.VaryByQueryKeys ?? ((cacheProfile != null) ? cacheProfile.VaryByQueryKeys : null));
return new ResponseCacheFilter(new CacheProfile
{
Duration = this._duration,
Location = this._location,
NoStore = this._noStore,
VaryByHeader = this.VaryByHeader,
VaryByQueryKeys = this.VaryByQueryKeys
});
}
可以得知Action上设置-----优先级高于--CacheProfiles里面的配置
缓存最终通过ResponseCacheFilter过滤器来实现,ResponseCacheFilter 的代码:
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Core;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.ResponseCaching;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
namespace Microsoft.AspNetCore.Mvc.Internal
{
/// <summary>
/// An <see cref="T:Microsoft.AspNetCore.Mvc.Filters.IActionFilter" /> which sets the appropriate headers related to response caching.
/// </summary>
public class ResponseCacheFilter : IResponseCacheFilter, IActionFilter, IFilterMetadata
{
private readonly CacheProfile _cacheProfile;
private int? _cacheDuration;
private ResponseCacheLocation? _cacheLocation;
private bool? _cacheNoStore;
private string _cacheVaryByHeader;
private string[] _cacheVaryByQueryKeys;
/// <summary>
/// Gets or sets the duration in seconds for which the response is cached.
/// This is a required parameter.
/// This sets "max-age" in "Cache-control" header.
/// </summary>
public int Duration
{
get
{
return (this._cacheDuration ?? this._cacheProfile.Duration) ?? 0;
}
set
{
this._cacheDuration = value;
}
}
/// <summary>
/// Gets or sets the location where the data from a particular URL must be cached.
/// </summary>
public ResponseCacheLocation Location
{
get
{
return (this._cacheLocation ?? this._cacheProfile.Location) ?? ResponseCacheLocation.Any;
}
set
{
this._cacheLocation = value;
}
}
/// <summary>
/// Gets or sets the value which determines whether the data should be stored or not.
/// When set to <see langword="true" />, it sets "Cache-control" header to "no-store".
/// Ignores the "Location" parameter for values other than "None".
/// Ignores the "duration" parameter.
/// </summary>
public bool NoStore
{
get
{
return (this._cacheNoStore ?? this._cacheProfile.NoStore) ?? false;
}
set
{
this._cacheNoStore = value;
}
}
/// <summary>
/// Gets or sets the value for the Vary response header.
/// </summary>
public string VaryByHeader
{
get
{
return this._cacheVaryByHeader ?? this._cacheProfile.VaryByHeader;
}
set
{
this._cacheVaryByHeader = value;
}
}
/// <summary>
/// Gets or sets the query keys to vary by.
/// </summary>
/// <remarks>
/// <see cref="P:Microsoft.AspNetCore.Mvc.Internal.ResponseCacheFilter.VaryByQueryKeys" /> requires the response cache middleware.
/// </remarks>
public string[] VaryByQueryKeys
{
get
{
return this._cacheVaryByQueryKeys ?? this._cacheProfile.VaryByQueryKeys;
}
set
{
this._cacheVaryByQueryKeys = value;
}
}
/// <summary>
/// Creates a new instance of <see cref="T:Microsoft.AspNetCore.Mvc.Internal.ResponseCacheFilter" />
/// </summary>
/// <param name="cacheProfile">The profile which contains the settings for
/// <see cref="T:Microsoft.AspNetCore.Mvc.Internal.ResponseCacheFilter" />.</param>
public ResponseCacheFilter(CacheProfile cacheProfile)
{
this._cacheProfile = cacheProfile;
}
/// <inheritdoc />
public void OnActionExecuting(ActionExecutingContext context)
{
//IL_0008: Unknown result type (might be due to invalid IL)
//IL_0051: Unknown result type (might be due to invalid IL)
//IL_00d4: Unknown result type (might be due to invalid IL)
//IL_0185: Unknown result type (might be due to invalid IL)
if (context == null)
{
throw new ArgumentNullException("context");
}
if (!this.IsOverridden(context))
{
if (!this.NoStore && !this._cacheProfile.Duration.get_HasValue() && !this._cacheDuration.get_HasValue())
{
throw new InvalidOperationException(Resources.FormatResponseCache_SpecifyDuration("NoStore", "Duration"));
}
IHeaderDictionary headers = context.HttpContext.Response.Headers;
((IDictionary)(?)headers).Remove((!0)"Vary");
((IDictionary)(?)headers).Remove((!0)"Cache-Control");
((IDictionary)(?)headers).Remove((!0)"Pragma");
if (!string.IsNullOrEmpty(this.VaryByHeader))
{
headers["Vary"] = this.VaryByHeader;
}
if (this.VaryByQueryKeys != null)
{
IResponseCachingFeature responseCachingFeature = context.HttpContext.Features.Get<IResponseCachingFeature>();
if (responseCachingFeature == null)
{
throw new InvalidOperationException(Resources.FormatVaryByQueryKeys_Requires_ResponseCachingMiddleware("VaryByQueryKeys"));
}
responseCachingFeature.VaryByQueryKeys = this.VaryByQueryKeys;
}
if (this.NoStore)
{
headers["Cache-Control"] = "no-store";
if (this.Location == ResponseCacheLocation.None)
{
headers.AppendCommaSeparatedValues("Cache-Control", "no-cache");
headers["Pragma"] = "no-cache";
}
}
else
{
string text = null;
switch (this.Location)
{
case ResponseCacheLocation.Any:
text = "public";
break;
case ResponseCacheLocation.Client:
text = "private";
break;
case ResponseCacheLocation.None:
text = "no-cache";
headers["Pragma"] = "no-cache";
break;
}
text = string.Format((IFormatProvider)CultureInfo.get_InvariantCulture(), "{0}{1}max-age={2}", (object)text, (object)((text != null) ? "," : null), (object)this.Duration);
if (text != null)
{
headers["Cache-Control"] = text;
}
}
}
}
/// <inheritdoc />
public void OnActionExecuted(ActionExecutedContext context)
{
}
internal bool IsOverridden(ActionExecutingContext context)
{
//IL_0008: Unknown result type (might be due to invalid IL)
if (context == null)
{
throw new ArgumentNullException("context");
}
return Enumerable.Last<IResponseCacheFilter>(Enumerable.OfType<IResponseCacheFilter>((IEnumerable)context.Filters)) != this;
}
}
}
c#基础,单线程,跨线程访问和线程带参数
1 using System;
2 using System.Collections.Generic;
3 using System.Threading;
4 using System.Windows.Forms;
5
6 namespace 线程和跨线程
7 {
8 public partial class Form1 : Form
9 {
10 public Form1()
11 {
12 InitializeComponent();
13 }
14 /// <summary>
15 /// 单线程直接假死了
16 /// </summary>
17 /// <param name="sender"></param>
18 /// <param name="e"></param>
19 private void btnAlone_Click(object sender, EventArgs e)
20 {
21 for (int i = 0; i < 100000; i++)
22 {
23 //通过[调试]-[窗口]-[输出]显示打印值
24 Console.WriteLine(i);
25 }
26 }
27
28
29 /// <summary>
30 /// 新线程运行,窗体不假死
31 /// </summary>
32 /// <param name="sender"></param>
33 /// <param name="e"></param>
34 private void btnNew_Click(object sender, EventArgs e)
35 {
36 Thread th = new Thread(ShowCalculator)
37 {
38 IsBackground = true
39 };
40 th.Start();
41
42 }
43 /// <summary>
44 /// 循环计算方法,供新线程使用
45 /// </summary>
46 private void ShowCalculator()
47 {
48 for (int i = 0; i < 100000; i++)
49 {//通过[调试]-[窗口]-[输出]显示打印值
50 Console.WriteLine(i);
51 }
52 }
53 /// <summary>
54 /// 带参数的
55 /// </summary>
56 /// <param name="sender"></param>
57 /// <param name="e"></param>
58 private void btnParameters_Click(object sender, EventArgs e)
59 {
60 List<int> list = new List<int>() { 1, 2, 3, 4, 5 };
61 ParameterizedThreadStart parThreadStart = new ParameterizedThreadStart(ShowParameters);
62 Thread th = new Thread(parThreadStart) { IsBackground = true };
63 th.Start(list);
64 }
65 private void ShowParameters(object obj)
66 {
67 //线程中的参数只能是Object
68 List<int> result = obj as List<int>;
69 foreach (var item in result)
70 {
71 MessageBox.Show(item.ToString());
72 }
73 }
74 /// <summary>
75 /// 跨线程访问
76 /// </summary>
77 /// <param name="sender"></param>
78 /// <param name="e"></param>
79 private void button1_Click(object sender, EventArgs e)
80 {
81 Thread th = new Thread(ShowMulti) { IsBackground = true };
82 th.Start();
83 }
84 /// <summary>
85 /// 解决跨线程访问报异常,不使用
86 /// </summary>
87 private void ShowMulti()
88 {
89 int first = 0;
90 for (int i = 0; i < 10; i++)
91 {
92 first = i;
93 }
94 //是否要对lbl控件进行跨线程
95 if (this.lblShow.InvokeRequired)
96 {
97 //对委托中的数据类型验证
98 this.lblShow.Invoke(new Action<Label, string>(ShowLableValue), this.lblShow, first.ToString());
99 }
100 else
101 {
102 this.lblShow.Text = first.ToString();
103 }
104 }
105 /// <summary>
106 /// 把值写到控件中
107 /// </summary>
108 /// <param name="lbl"></param>
109 /// <param name="value"></param>
110 private void ShowLableValue(Label lbl, string value)
111 {
112 lbl.Text = value;
113 }
114
115 private void Form1_Load(object sender, EventArgs e)
116 {
117 //关闭跨进程检查
118 //Label.CheckForIllegalCrossThreadCalls = false;
119 //改用委托方法实现
120 }
121 }
122 }
wpf 禁用启用webbroswer右键菜单
//禁用脚本错误等类似的窗口信息
this.webBrowser1.ScriptErrorsSuppressed = true;
//禁用右键菜单
this.webBrowser1.IsWebBrowserContextMenuEnabled = false;
//禁用键盘快捷键
this.webBrowser1.WebBrowserShortcutsEnabled = false;
//打开IE打印机会话框
this.webBrowser1.ShowPrintDialog();
//打开IE的打印预览会话框
this.webBrowser1.ShowPrintPreviewDialog();
//打开IE的保存 会话框
this.webBrowser1.ShowSaveAsDialog();
EF Core 2.0使用MsSql/MySql实现DB First和Code First
参考地址
ASP.NET Core MVC 和 EF Core - 教程系列
环境
开始搭建
1、在 Visual Studio 2017 中创建新项目
- “文件”>“新建”>“项目”
- 从左侧菜单中选择“已安装”>“模板”>“Visual C#”>“.NET Core”。
- 选择“ASP.NET Core Web 应用程序”。
- 输入“EFGetStarted.AspNetCore.NewDb”作为名称,然后单击“确定”。
- 在“新建 ASP.NET Core Web 应用程序”对话框中:
- 确保在下拉列表中选择“.NET Core”和“ASP.NET Core 2.0”选项
- 选择“Web 应用程序(模型视图控制器)”项目模板
- 确保将“身份验证”设置为“无身份验证”
- 单击“确定”
2、安装 Entity Framework Core
- 工具”>“NuGet 包管理器”>“包管理器控制台”
1.1、安装数据库提供程序
MsSql
运行:Install-Package Microsoft.EntityFrameworkCore.SqlServer
MySql
运行:柚子:Install-Package Pomelo.EntityFrameworkCore.MySql
或者
官方:Install-Package MySql.Data.EntityFrameworkCore -Version 8.0.11
1.2、安装程序包管理器控制台
运行:Install-Package Microsoft.EntityFrameworkCore.Tools
1.3、安装设计包
运行:Install-Package Microsoft.EntityFrameworkCore.Design
数据据库提供程序设计包 (EF Core 2.0 不再需要)
MsSql
运行:Install-Package Microsoft.EntityFrameworkCore.SqlServer.Design
MySql
运行:Install-Package Pomelo.EntityFrameworkCore.MySql.Design
DB First——从现有数据库创建模型
MySql
运行:Scaffold-DbContext -Connection "Server=localhost;User Id=root;Password=123456;Database=vanfj" -Provider "Pomelo.EntityFrameworkCore.MySql" -OutputDir "Models"
MsSql
运行:Scaffold-DbContext -Connection "Server=localhost;User Id=root;Password=123456;Database=vanfj" -Provider "Microsoft.EntityFrameworkCore.SqlServer" -OutputDir "Models"
使用说明:将Connection中的连接字符串替换为自己的数据库连接,将OutputDir中的Models替换为自己要生成的文件目录名
Code First——从模型生成到数据库
1、创建模型
1.1、创建上下文
public class SchoolContext : DbContext
{
public SchoolContext(DbContextOptions<SchoolContext> options) : base(options)
{
}
public DbSet<Course> Courses { get; set; }
public DbSet<Enrollment> Enrollments { get; set; }
public DbSet<Student> Students { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Course>().ToTable("Course");
modelBuilder.Entity<Enrollment>().ToTable("Enrollment");
modelBuilder.Entity<Student>().ToTable("Student");
}
}
public class Student
{
public int ID { get; set; }
public string LastName { get; set; }
public string FirstMidName { get; set; }
public DateTime EnrollmentDate { get; set; }
public ICollection<Enrollment> Enrollments { get; set; }
}
public enum Grade
{
A, B, C, D, F
}
public class Enrollment
{
public int EnrollmentID { get; set; }
public int CourseID { get; set; }
public int StudentID { get; set; }
public Grade? Grade { get; set; }
public Course Course { get; set; }
public Student Student { get; set; }
}
{
A, B, C, D, F
}
public class Enrollment
{
public int EnrollmentID { get; set; }
public int CourseID { get; set; }
public int StudentID { get; set; }
public Grade? Grade { get; set; }
public Course Course { get; set; }
public Student Student { get; set; }
}
public class Course
{
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int CourseID { get; set; }
public string Title { get; set; }
public int Credits { get; set; }
public ICollection<Enrollment> Enrollments { get; set; }
}
1.2、Startup文件注入上下文
EF Core在版本 2.0 中,引入了一种在依赖关系注入中注册自定义 DbContext 类型的新方法,即以透明形式引入可重用 DbContext 实例的池。
要使用 DbContext 池,请在服务注册期间使用 AddDbContextPool 而不是 AddDbContext
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContextPool<SchoolContext>(options =>
options.UseMySql(Configuration.GetConnectionString("DefaultConnection")));
services.AddMvc().AddJsonOptions(options =>
options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore);
}
1.3、appsettings.json文件添加连接字符串
{
"ConnectionStrings": {
"DefaultConnection": "Server=localhost;User Id=root;Password=123456;Database=vanfj"
},
"Logging": {
"IncludeScopes": false,
"LogLevel": {
"Default": "Warning"
}
}
}
2、执行NuGet命令,创建数据库
2.1、为迁移搭建基架
运行:Add-Migration InitialCreate
2.2、将新迁移应用到数据库
运行:Update-Database
EF Core 2.0 NuGet命令
Get-Help about_EntityFrameworkCore 获取EF Core命令帮助
添加一个迁移数据库 迁移的名称 目录(及其子命名空间)路径是相对于项目目录。 默认值为"Migrations"。
Add-Migration -Name <String> -OutputDir <String>
Add-Migration InitialCreate 第一次执行初始化用这个
删除上次的迁移数据库 不检查以查看迁移是否已应用到数据库。
Remove-Migration -Force
目标迁移。 如果为"0",将恢复所有迁移。 默认到最后一个迁移。
Update-Database
Update-Database LastGoodMigration 还原迁移
删除数据库 显示的数据库会被丢弃,但没有删除它
Drop-Database -WhatIf
Get-DbContext 获取有关 DbContext 类型的信息
从数据库更新DbContext和实体的类型
Scaffold-DbContext
-Connection <String> 数据库的连接字符串。
-Provider <String> 要使用的提供程序。 (例如 Microsoft.EntityFrameworkCore.SqlServer)
-OutputDir <String > 要将文件放入的目录。 路径是相对于项目目录。
--Context <String > 若要生成的 dbcontext 名称。
-Schemas <String[]> 要生成实体类型的表架构。
-Tables <String[]> 要生成实体类型的表。
-DataAnnotations 使用属性来配置该模型 (如果可能)。 如果省略,则使用仅 fluent API。
-UseDatabaseNames 使用直接从数据库表和列名称。
-Force 覆盖现有文件。
从迁移中生成的 SQL 脚本
Script-Migration
-From <String> 开始迁移。 默认值为 0 (初始数据库)
-To <String> 结束的迁移。 默认到最后一个迁移
-Idempotent 生成可以在任何迁移的数据库使用的脚本
-Output <String> 要将结果写入的文件
ASP.NET Core部署到Windows IIS
网上已经有许多ASP.NET Core关于Widows IIS部署的文章,在部署到服务器时遇到了一些问题,在这里我就不再对原理进行阐释(复制)了,只写下一些关键环节,想看原理的同学请参考官网,此文章作为留用。
步骤:
1、ASP.NET Core程序内配置
2、Windows Server配置
一、ASP.NET Core应用程序配置
web.config 配置(官方教程)
重点修改 processPath 和 arguments 两个参数
processPath 修改为 dotnet
arguments 修改为 当前项目名称的dll
配置示例:

Startup 启用 IISIntegration 组件

FTP发布到IIS
在这里我使用的是VS FTP直接发布到IIS,也可以使用文件系统先发布到本地,两者任选一种都可以

二、Windows Server配置
安装环境
1、 Microsoft Visual C ++ 2015 Redistributable
目前这里这里链接的版本是DotNetCore.2.0.7-WindowsHosting,也可以在.NET所有下载自行选择对应的版本
提示:版本很重要,版本很重要,版本很重要
IIS配置

应用程序池设置为无托管代码

最后来测试是否成功

QRCode.js:使用 JavaScript 生成二维码
什么是 QRCode.js?
QRCode.js 是一个用于生成二维码的 JavaScript 库。主要是通过获取 DOM 的标签,再通过 HTML5 Canvas 绘制而成,不依赖任何库。
基本用法
载入 JavaScript 文件
<script type="text/javascript" src="http://static.runoob.com/assets/qrcode/qrcode.min.js"></script>
DOM结构
<div id="qrcode"></div>
JavaScropt调用
//简单形式
new QRCode(document.getElementById("qrcode"), "http://www.runoob.com"); // 设置要生成二维码的链接
// 设置参数方式
var qrcode = new QRCode("test", {
text: "http://www.runoob.com",
width: 128,
height: 128,
colorDark : "#000000",
colorLight : "#ffffff",
correctLevel : QRCode.CorrectLevel.H
});
// 使用 API
qrcode.clear();
qrcode.makeCode('new content');
参数说明
new QRCode(element, option)
| 名称 | 默认值 | 说明 |
|---|---|---|
| element | - | 显示二维码的元素或该元素的 ID |
| option | 参数配置 |
option 参数说明
| 名称 | 默认值 | 说明 |
|---|---|---|
| width | 256 | 图像宽度 |
| height | 256 | 图像高度 |
| colorDark | "#000000" | 前景色 |
| colorLight | "#ffffff" | 背景色 |
| correctLevel | QRCode.CorrectLevel.L | 容错级别,可设置为:
QRCode.CorrectLevel.L QRCode.CorrectLevel.M QRCode.CorrectLevel.Q QRCode.CorrectLevel.H |
API 接口
| 名称 | 说明 |
|---|---|
| makeCode(text) | 设置二维码内容 |
| clear() | 清除二维码。(仅在不支持 Canvas 的浏览器下有效) |
浏览器支持
支持该库的浏览器有:IE6~10, Chrome, Firefox, Safari, Opera, Mobile Safari, Android, Windows Mobile, 等。
实例代码
HTML 代码
<input id="text" type="text" value="http://www.runoob.com" /><br /> <div id="qrcode"></div>
CSS 代码
#qrcode {
width:160px;
height:160px;
margin-top:15px;
}
JavaScript 代码
var qrcode = new QRCode("qrcode");
function makeCode () {
var elText = document.getElementById("text");
if (!elText.value) {
alert("Input a text");
elText.focus();
return;
}
qrcode.makeCode(elText.value);
}
makeCode();
$("#text").
on("blur", function () {
makeCode();
}).
on("keydown", function (e) {
if (e.keyCode == 13) {
makeCode();
}
});
HTML完整代码
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ko" lang="ko">
<head>
<title>Javascript 二维码生成库:QRCode</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no" />
<script type="text/javascript" src="http://cdn.bootcss.com/jquery/2.1.1/jquery.min.js"></script>
<script type="text/javascript" src="http://static.runoob.com/assets/qrcode/qrcode.min.js"></script>
</head>
<body>
<input id="text" type="text" value="http://www.runoob.com" style="width:80%" /><br />
<div id="qrcode" style="width:100px; height:100px; margin-top:15px;"></div>
<script type="text/javascript">
var qrcode = new QRCode(document.getElementById("qrcode"), {
width : 100,
height : 100
});
function makeCode () {
var elText = document.getElementById("text");
if (!elText.value) {
alert("Input a text");
elText.focus();
return;
}
qrcode.makeCode(elText.value);
}
makeCode();
$("#text").
on("blur", function () {
makeCode();
}).
on("keydown", function (e) {
if (e.keyCode == 13) {
makeCode();
}
});
</script>
</body>
</html>



浙公网安备 33010602011771号