看到网上很多链接文件(word、pdf...)可以下载,想制作http下载链接。

其实是将某文件直接放在服务器上搭建的网站上某目录下即可,例如:http://xxx:port/UpgradePack/525.jpg 或者  http://xxx:port//博客.pdf。

http服务器有很多种, 如tomcat,apache,IIS等,也可以直接下载http服务器hfs(http file server)快速搭建。

一、利用C#模拟文件上传至服务器

主要有以下三种基本方法:

方法一:用Web控件FileUpload

上传到网站根目录,适用于asp.net webForm

 <form id="form1" runat="server">
<%--上传文件大小有限制--%>
<asp:FileUpload ID="FileUpload1" AllowMultiple="true" runat="server" />
<br />
<br />
<%--直接进FileUploadTest.aspx.cs中处理--%>
<asp:Button ID="Button1" runat="server" Text="上传到服务器" OnClick="Button1_Click" />
<asp:Label ID="Label1" runat="server" Text="" Style="color: Red"></asp:Label>
</form> protected void Button1_Click(object sender, EventArgs e)
{
//处理单个文件
//if(FileUpload1.HasFile)
//{
// FileUpload1.SaveAs(Server.MapPath("~/Files/") + FileUpload1.FileName);
// Label1.Text = "上传成功";
//}
//else
//{
// Label1.Text = "上传失败";
//} if (FileUpload1.HasFile)
{
foreach (var item in FileUpload1.PostedFiles)
{
FileUpload1.SaveAs(Server.MapPath("~/Files/") + item.FileName);
}
Label1.Text = "上传成功";
}
else
{
Label1.Text = "上传失败";
}
}

允许一次选择多个文件:AllowMultiple="true"

注意:FileUpLoad上传控件,限制文件上传大小默认4096kb(4MB)

如果我们要上传超过此大小的文件,会出现错误界面等……

如果想增大允许上传的文件大小,则需要修改web.config文件代码:

<configuration>
<system.web>
<httpRuntime maxRequestLength="4096" executionTimeout="120"/>
</system.web>
</configuration>

说明:

maxRequestLength属性限制文件上传的大小,是以KB为单位的,默认值为4096KB,而最大上限为2097151KB,大约是2GB。

executionTimeout属性限制文件上传的时间,以秒(s)为单位,默认值为90 s,如果您考虑到所设计的Web应用系统上传时间要超过90 s可延长设定值。

方法二:用Html控件HtmlInputFile

     <form id="form1" runat="server">
<input type="file" id="file1" runat="server" />
<asp:Button ID="Button1" runat="server" Text="上传" OnClick="Button1_Click" />
<asp:Label ID="Label1" runat="server" Text="" Style="color: Red"></asp:Label>
</form> protected void Button1_Click(object sender, EventArgs e)
{
if (file1.PostedFile.ContentLength > )
{
file1.PostedFile.SaveAs(Server.MapPath("~/") + Path.GetFileName(file1.PostedFile.FileName));
Label1.Text = "上传成功!";
}
}

选择多个文件:multiple="multiple"  ,但是发现后端没有获取文件列表的方法/属性。不知道是不是这个HtmlInputFile只能单文件上传,有哪位清楚,还望告知下。

注意两个区别:

一:FileUpload.FileName获取客户端上传文件名(不带路径),而file1.PostedFile.FileName 和Request.Files["file"].FileName在不同浏览器下情况不同:IE8下获得的是客户端上传文件的完全限定名(带路径),谷歌、苹果等浏览器下则仍为文件名(不带路径)。

二:FileUpload控件有HasFile属性,用于判断用户是否选择了上传文件,而后面两种方法则需要通过判断上传文件大小ContentLength属性,当用户没有选择上传文件时,该属性值为0。

可以看出FileUpload封装程度更高,但灵活性也稍差。

方法三:Html元素input type="file"

  • 通过表单提交,获取Request.Files
 <%-- enctype 属性规定在发送到服务器之前应该如何对表单数据进行编码。[在使用包含文件上传控件的表单时,必须使用multipart/form-data。]--%>
<form id="form1" runat="server" enctype="multipart/form-data">
<input type="file" name="file" multiple="multiple" />
<br />
<br />
<input type="text" name="author" value="huy" />
<asp:Button ID="Button1" runat="server" Text="上传到服务器" OnClick="Button1_Click" />
<asp:Label ID="Label1" runat="server" Text="" Style="color: Red"></asp:Label>
</form> protected void Button1_Click(object sender, EventArgs e)
{
string name = Request.Form["author"];
Response.Write(name);
HttpFileCollection files = Request.Files;
if (files.Count > 0)
{
for (int i = 0; i < files.Count; i++)
{
files[i].SaveAs(Server.MapPath("~/Files/") + Path.GetFileName(files[i].FileName));
}
Label1.Text = "上传成功";
}
else
{
Label1.Text = "上传失败";
}
}

注意:form需要设置,enctype="multipart/form-data"。。多文件上传(multiple="multiple")  HTML5中支持

官网参考:HttpRequest.Files

  • 也可以利用Ajax提交,FormData(),上传的文件支持移除,
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="InputFileAjax.aspx.cs" Inherits="WebFormTest.FileUpload.InputFileAjax" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title></title>
<style>
/*为了不显示控件的 未选择任何文件/上传个数*/
.surfaceThree {
position: relative;
width: 80px;
background: gainsboro;
border-radius: 6px;
text-align: center;
line-height: 30px;
font-size: 16px;
color: black;
} .surfaceThree input {
position: absolute;
top: 5px;
right: -110px;
height: 30px;
/* 重点代码让input隐藏 */
opacity: 0;
}
</style> <script src="../Scripts/jquery-1.10.2.min.js"></script>
</head>
<body>
<form id="form1" runat="server">
<div id="email" runat="server">
</div> <div class="surfaceThree">
选择文件
<input type="file" multiple="multiple" name="fileUpload" id="fileUpload" onchange="uploadLogic(this)" />
</div>
<br />
<br />
<input type="text" name="author" value="huy" /> <asp:Button ID="Button1" runat="server" Text="上传到服务器" OnClick="Button1_Click" OnClientClick="return addFiles()" />
<asp:Label ID="Label1" runat="server" Text="" Style="color: Red"></asp:Label>
</form> <script type="text/javascript"> //单击上传的时候 增加手动选择的附件
function addFiles() {
var formData = new FormData();
for (var i = 0; i < fileLists.length; i++) {
formData.append('file', fileLists[i]); //file可以任意
} $.ajax({
url: "InputFileAjax.ashx",
data: formData,
type: "post",
async: false,
contentType: false,
processData: false,
success: function (msg) {
var rs = jQuery.parseJSON(data);
if (rs.ReturnCode == 1) {
console.log("手動添加附件成功");
} else if (rs.ReturnCode == 0) {
console.log(rs.Message);
}
else {
alert("手動添加附件失敗:" + rs.Message);
}
},
error: function (e) {
alert("手動添加附件失敗");
}
});
} fileLists = [];
//多文件上传逻辑
function uploadLogic(obj) {
var filrarr = obj.files;
//console.log("这次上传的文件:");
//console.log(filrarr);
if ((fileLists.length + filrarr.length) > 10) {
alert("手動添加附件不鞥超過10個!");
return;
}
files = Array.prototype.slice.call(filrarr); //需要能动态修改fileList即可,第一想法是将它转化为数组进行操作。
fileLists = fileLists.concat(files);
console.log("现在总的文件:");
console.log(fileLists); var email = $('#email');
for (var i = 0; i < filrarr.length; i++) { var addtr = $("<div style='margin: 5px 10px;display:inline-block'>" +
"<div class='label label-primary' title='" + filrarr[i].name + "' style='vertical-align: middle;margin-right: 10px;display:inline-block;width:150px;overflow: hidden; text-overflow: ellipsis;height:20px'>" +
filrarr[i].name + "</div>" +
"<input type=\"button\" id='btnRemoveAttach' style='color: red;border-radius: 6px' onclick='RemoveMulFileUpload(this,\"" + filrarr[i].name + "\")' value=\"移除\" />" +
"</div>");
email.append(addtr);
}
} //移除多文件上传控件的文件
function RemoveMulFileUpload(div, filename) {
var ind = $(div).parent().index();
fileLists.splice(ind, 1);//修改fileLists
$(div).parent().remove();
console.log("删除文件:" + filename + "。后现在总的文件:");
console.log(fileLists);
} </script>
</body>
</html>

注意:

1、processData参数:

用于对data参数进行序列化处理,默认值是true。默认情况下发送的数据将被转换为对象,对于文件File则不需要转换,此参数需要设置为false。否则可能报非法调用(Illegal invocation)。

2、普通参数传递与获取:

formData.append("param1","参数1");

string p1=Request.Form["param1"];  //普通参数获取

后端 一般处理页

using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web; namespace WebFormTest.FileUpload
{
/// <summary>
/// InputFileAjax1 的摘要说明
/// </summary>
public class InputFileAjax1 : IHttpHandler
{ public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "text/plain";
//context.Response.Write("Hello World");
AddUploadFiles(context); } /// <summary>
/// 增加手动上传的文件
/// </summary>
/// <param name="context"></param>
private void AddUploadFiles(HttpContext context)
{
var result = new Result() { ReturnCode = };
try
{
if (context.Request.Files.Count <= )
{
result.Message = "沒有額外添加附件";
context.Response.Write(JsonConvert.SerializeObject(result));
}
if (context.Request.Files.Count > )
{
result.Message = "手動添加附件不鞥超過10個";
context.Response.Write(JsonConvert.SerializeObject(result));
}
HttpFileCollection files = context.Request.Files;
if (files.Count > )
{
for (int i = ; i < files.Count; i++)
{
files[i].SaveAs(context.Server.MapPath("~/Files/") + Path.GetFileName(files[i].FileName));
}
}
context.Response.Write(JsonConvert.SerializeObject(result));
}
catch (Exception ex)
{
result.Message = ex.ToString();
context.Response.Write(JsonConvert.SerializeObject(result));
}
} public bool IsReusable
{
get
{
return false;
}
}
} public class Result
{
/// <summary>
/// 1成功,0错误
/// </summary>
public int ReturnCode { get; set; }
public string Message { get; set; }
}
}

其中:未选择任何文件/上传个数不显示

常规的是这样,

选择文件后,这个“未选择任何文件”则显示成 选择了几个文件。但是移除文件 这个个数不会变。所以想办法不需要显示这个。

      .surfaceThree {
position: relative;
/*height: 30px;*/
width: 80px;
background: gainsboro;
border-radius: 6px;
text-align: center;
line-height: 30px;
font-size:16px;
color: black;
} .surfaceThree input {
position: absolute;
top: 5px;
right: -110px;
/*color: #fff;*/
height: 30px;
/* 重点代码让input隐藏 */
opacity: 0;
} <div class="surfaceThree">选择文件
<input type="file" multiple="multiple" name="fileUpload" id="fileUpload" onchange="uploadLogic(this)" />
</div>

上传图片限制大小、类型、像素

用到input标签来上传图片。图片有很多格式我们只需要其中的几种,就需要对用户上传的文件进行验证,在HTML5中有一个新的属性:accept文件类型限制。但是通常我们会用javascript或jQuery编写方法进行验证图片的大小限制、类型判断、像素判断。

function handleChange(file) {
var fileTypes = [".jpg", ".png"]; //我们所需要的图片格式
var filePath = file.value;
if (filePath) {
var filePic = file.files[0]; //选择的文件内容--图片
var fileType = filePath.slice(filePath.indexOf(".")); //选择文件的格式
var fileSize = file.files[0].size; //选择文件的大
if (fileTypes.indexOf(fileType) == -1) { //判断文件格式是否符合要求
alert("文件格式不符合要求!");
return if (fileSize > 1024 * 1024) {
alert("文件大小不能超过1M!");
return var reader = new FileReader();
reader.readAsDataURL(filePic);
reader.onload = function (e) {
var data = e.target.result;
//加载图片获取图片真实宽度和高度
var image = new Image();
image.onload = function () {
var width = image.width;
var height = image.height;
if (width == 720 | height == 1280) { //判断文件像素
//上传图片
} else {
alert("图片尺寸应为:720*1280!");
return;
}
};
image.src = data;
};
} else {
return
}
}

表单提交

前端控件都应该有一个name属性和”当前值“,在提交时,它们将以 name=value 的形式做为提交数据的一部分。

前台form表单的提交方式有很多种,例如:

1、form表单submit直接提交的方法
2、Ajax提交的方法
j3、query提交的方法
这里总结一下ajax提交的两种方式:

1.serialize() 方法:
通过序列化表单值,创建 URL 编码文本字符串。我们可以选择一个或多个表单元素(比如 input 及/或 文本框),或者 form 元素本身。序列化的值可在生成 AJAX 请求时用于 URL 查询字符串中。
所用到的语法为:$("form").serialize()

提交方法的代码段:$('form').submit(function() {

alert($(this).serialize());
return false;
});

最终序列化后,表单中数据会以下面这种方式提交到后台:a=1&b=2&c=3&d=4&e=5
这种方式处理表单时所适用的input标签类型是有限的,只适用于一些常用的类型例如text、checkbox、select、date等等,但是对于file文件类型的input框并不适用,那我们在用到ajax提交方式的时候应该如何提交file类型的input框数据呢?

2.封装FormData 对象,直接用$.ajax提交
将form表单中的内容封装成formdata的数据格式
FormData 对象可以把form中所有表单元素的name与value组成一个queryString,提交到后台,在使用Ajax提交时,使用FormData对象可以减少拼接queryString的工作量。

FormData的使用方法也是非常简单,直接传入form表单对象即可,如下:

var form = $('#form1');
var formdata = new FormData(form);
使用这种方式将数据封装后,file类型的文件数据即可以键值对的方式封装在formdata中,然后用ajx提交,方法如下:

$.ajax({
type : "POST",
url : "houtai/123.do",
data : formData,
async: false,
cache: false,
contentType: false,
processData: false,
success : function(msg) {
if(msg){
alert('提交成功!');
}
}
});

需要注意的是:以formdata的方式提交时需要添加async: false, 同步,否则后台无法接收到前台传过来的file文件数据,这样的提交方式,既可以提交任何一种type类型标签,又可以在提交之后得到返回结果,方便快捷又实用。

form表单提交过程

二、IIS搭建HTTP文件服务器(文件上传下载)

IIS环境准备

1、  安装IIS

打开“控制面板”,找到“程序与功能”, 找到“启用或关闭Windows功能”,点进去之后,将“Internet Information Services”下所有节点都打勾(这样就搭建了一个功能完全的HTTP/FTP服务器),注意“WebDAV发布”必须要安装,这个跟文件服务器中文件访问权限有着很大的关系,如果想对服务器中某个具有读写权限的文件夹进行读写,就必须开启该选项,如下图所示:

2、  添加网站

添加自己的一个网站,鼠标移到“网站”上方,右键点击鼠标,弹出菜单,在菜单中点击“添加网站”,如下图所示:

根据如下图所说的步骤,填写网站名称及选择物理路径,其他默认即可,然后点击“确定”按钮:

本网站仅作为文件服务器,因此,将服务器的文件浏览功能打开,以便浏览,具体操作为鼠标双击“目录浏览”后,将“操作”一栏里的“启用”打开,如下图所示:

3、WebDAV创作规则

进入,点击“WebDAV设置”,将①②所示红色框内的属性设置为图中所示的属性,并点击“应用”,如下图所示:

返回到“WebDAV创作规则”,点击“添加创作规则”,如下图所示:

在弹出的“添加创作规则”,将“允许访问此内容”选中,权限“读取、源、写入”都打勾,点击“确定”按钮关闭,如下图所示:

返回到“WebDAV创作规则”,点击“启用WebDAV”,

双击“身份验证”,将“匿名身份验证”(客户端读取文件)及“Windows身份验证”(客户端写入、删除)启用,如下所示:

 

为了能让文件服务器具有写入、删除功能,可以在现有Windows系统账户上新建一个隶属于“Power Users”的账户“test”(密码:123),如下图所示:

以上关于如何创建账户的内容,请自行百度

为了能让test账户顺利访问存放于E盘下的“TestWebSite”文件夹,需要为该文件夹设置Power Users组的访问权限,如下图所示:

关于如何将特定组或用户设置权限的问题,请自行百度。

查看本机IIS的IP地址,并在浏览器输入该IP,将会显示网站下内容。

自此,IIS文件服务器的搭建已经完毕。

使用C# WebClient访问IIS文件服务器 

在使用WebClient类之前,必须先引用System.Net命名空间,文件下载、上传与删除的都是使用异步编程,也可以使用同步编程,

这里以异步编程为例:

1)  文件下载:

//下载文件
string fileHttpPath = @"http://localhost/js/javascript/01.js";
string saveName = @"E:\IIS_Deploy\FileSystem\01.js";
SY.Filer.Http.HttpDownloadFile.DownloadFileAsync(fileHttpPath,saveName);
Console.WriteLine("文件下载结束"); /// <summary>
/// http文件下载
/// </summary>
public class HttpDownloadFile
{
/// <summary>
/// 异步文件下载
/// </summary>
/// <param name="fileHttpPath">文件的http路径</param>
/// <param name="saveLocalName">本地保存的文件名称</param>
public static void DownloadFileAsync(string fileHttpPath, string saveLocalName)
{
try
{
using (WebClient client = new WebClient())
{
//使用默认的凭据——读取的时候,只需默认凭据就可以
client.Credentials = CredentialCache.DefaultCredentials;
Uri uri = new Uri(fileHttpPath); client.DownloadProgressChanged += Client_DownloadProgressChanged;
client.DownloadFileCompleted += Client_DownloadFileCompleted;
//异步下载指定路径
client.DownloadFileAsync(uri, saveLocalName);
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
} //下载完成事件处理程序
private static void Client_DownloadFileCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
{
if (e.Cancelled)
{
Console.WriteLine("文件下载被取消");
}
//获取一个值,该值指示异步操作期间发生的错误
if (e.Error == null)
{
Console.WriteLine("文件下载成功");
}
else
{
//throw e.Error; //【异步操作 上层捕获不到】
Console.WriteLine(e.Error.ToString());
}
} //下载进度事件处理程序
private static void Client_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
Console.WriteLine($"{e.ProgressPercentage}:{e.BytesReceived}/{e.TotalBytesToReceive}");
}
}

2)  文件上传:

 //下载上传
string fileHttpPath = @"http://localhost/txt/Readme.txt";
string localfile = @"D:\0、入职20180820\Readme.txt";
SY.Filer.Http.HttpUploadFile.UploadFileAsync(fileHttpPath, localfile);
Console.WriteLine("文件上传结束"); /// <summary>
/// http文件上传
/// </summary>
public class HttpUploadFile
{
/// <summary>
/// 异步文件上传
/// </summary>
/// <param name="fileSaveHttpPath">文件的http路径</param>
/// <param name="saveLocalName">本地的文件名称</param>
public static void UploadFileAsync(string fileSaveHttpPath, string localFile)
{
try
{
using (WebClient client = new WebClient())
{
//client.Credentials = CredentialCache.DefaultCredentials; //使用Windows登录方式
client.Credentials = new NetworkCredential("test", "hy123456@");
Uri _uri = new Uri(fileSaveHttpPath); //注册上传进度事件通知
client.UploadProgressChanged += Client_UploadProgressChanged;
client.UploadFileCompleted += Client_UploadFileCompleted; //异步 将选择的上传文件到服务器
client.UploadFileAsync(_uri, "PUT", localFile);
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
} //上传完成事件处理程序
private static void Client_UploadFileCompleted(object sender, UploadFileCompletedEventArgs e)
{
if (e.Cancelled)
{
Console.WriteLine("文件上传被取消");
return;
}
//获取一个值,该值指示异步操作期间发生的错误
if (e.Error == null)
{
Console.WriteLine("文件上传成功");
}
else
{
//throw e.Error; //【异步操作 上层捕获不到】
Console.WriteLine(e.Error.ToString());
}
}
//上传进度事件处理程序
private static void Client_UploadProgressChanged(object sender, UploadProgressChangedEventArgs e)
{
Console.WriteLine($"{e.ProgressPercentage}:{e.BytesSent}/{e.TotalBytesToSend}");
} }

三、异常及解决方案

1、上传文件报错:远程服务器返回错误: (409) 冲突

  由于服务器上不存在上传文件设定的目录,而webclient不会自动创建文件夹所导致。手工创建对应的文件夹即可。

2、上传文件报错:远程服务器返回错误: (403) 已禁止

   服务器上文件夹未设置用户组某用户的访问权限

HTTP文件上传的更多相关文章

  1. jquery.uploadify文件上传组件

    1.jquery.uploadify简介 在ASP.NET中上传的控件有很多,比如.NET自带的FileUpload,以及SWFUpload,Uploadify等等,尤其后面两个控件的用户体验比较好, ...

  2. 11、Struts2 的文件上传和下载

    文件上传 表单准备 要想使用 HTML 表单上传一个或多个文件 须把 HTML 表单的 enctype 属性设置为 multipart/form-data 须把 HTML 表单的method 属性设置 ...

  3. Java FtpClient 实现文件上传服务

    一.Ubuntu 安装 Vsftpd 服务 1.安装 sudo apt-get install vsftpd 2.添加用户(uftp) sudo useradd -d /home/uftp -s /b ...

  4. 小兔Java教程 - 三分钟学会Java文件上传

    今天群里正好有人问起了Java文件上传的事情,本来这是Java里面的知识点,而我目前最主要的精力还是放在了JS的部分.不过反正也不麻烦,我就专门开一贴来聊聊Java文件上传的基本实现方法吧. 话不多说 ...

  5. ,net core mvc 文件上传

    工作用到文件上传的功能,在这个分享下 ~~ Controller: public class PictureController : Controller { private IHostingEnvi ...

  6. Web开发安全之文件上传安全

    很长一段时间像我这种菜鸡搞一个网站第一时间反应就是找上传,找上传.借此机会把文件上传的安全问题总结一下. 首先看一下DVWA给出的Impossible级别的完整代码: <?php if( iss ...

  7. AutoIt实现Webdriver自动化测试文件上传

    在运用WebDriver进行自动化测试时,由于WebDriver自身的限制,对于上传文件时Windows弹出的文件选择窗口无法控制,通过在网上查找资料锁定使用AutoIt来控制文件上传窗口. Auto ...

  8. Struts的文件上传下载

    Struts的文件上传下载 1.文件上传 Struts2的文件上传也是使用fileUpload的组件,这个组默认是集合在框架里面的.且是使用拦截器:<interceptor name=" ...

  9. .JavaWeb文件上传和FileUpload组件使用

    .JavaWeb文件上传 1.自定义上传 文件上传时的表单设计要符合文件提交的方式: 1.提交方式:post 2.表单中有文件上传的表单项:<input type="file" ...

  10. ASP.NET MVC5+EF6+EasyUI 后台管理系统(32)-swfupload多文件上传[附源码]

    系列目录 文件上传这东西说到底有时候很痛,原来的asp.net服务器控件提供了很简单的上传,但是有回传,还没有进度条提示.这次我们演示利用swfupload多文件上传,项目上文件上传是比不可少的,大家 ...

随机推荐

  1. Nginx 配置 HTTP 跳转 HTTPS-Linux运维日志

    本文介绍 Nginx 访问 HTTP 跳转 HTTPS 的 4 种配置方式. rewrite Nginx rewrite 有四种 flag: break:在一个请求处理过程中将原来的 url 改写之后 ...

  2. 我的Vue朝圣之路2

    1.创建第一个Vue案例 1. 引入Vue.js   2. 创建Vue对象      el : 指定根element(选择器)      data : 初始化数据(页面可以访问)  3. 双向数据绑定 ...

  3. wpf Log4net的配置和使用

    现在项目涉及的是cs客户端,在项目中使用log4net记录本地日志和异常信息,这里项目做完了,想着自己做一个demo,测试记录一下log4Net的配置使用. 第一步.新建一个wpf应用程序,项目右键 ...

  4. 图解Apache Mina

    Apache MINA 是一个用于简化开发构建高性能.高可扩展的网络应用框架.通过JAVA NIO在各种传输协议(如:TCP/IP.UDP/IP)上提供抽象的事件驱动异步API Apache MINA ...

  5. iOS - WebRTC的实现原理

    再简单地介绍一下webrtc: WebRTC,名称源自网页实时通信(Web Real-Time Communication)的缩写,简而言之它是一个支持网页浏览器进行实时语音对话或视频对话的技术. 它 ...

  6. 在SQL Server中,为何都建议禁止 VIA 协议,VIA协议具体内容是什么?

    在SQL Server 在SQL Server中,为何都建议禁止 VIA 协议,VIA协议具体内容是什么? 中,为何都建议禁止 VIA 协议,VIA协议具体内容是什么? 在SQL Server中,为何 ...

  7. SpringBoot+SpringCloud+vue+Element开发项目——集成Druid数据源

    添加依赖 pom.xml <!--druid--> <dependency> <groupId>com.alibaba</groupId> <ar ...

  8. python代码工具小结

    目录: 1.with读.写文件 (1)with读文件 (2)with写文件 2.requests爬虫 (1)get请求 (2)post请求 1.with读.写文件 (1)with读文件 (2)with ...

  9. c# CryptoStream 类

  10. c# Unicode