C#--图片上传(PC端和APP)保存及 跨域上传说明
手动跨域操作文件
补录:跨域访问文件夹文件是一种常见的需求,下面主要介绍的的通过代码使用具有权限账号的人来达到跨域操作文件的能力。
现在补充一下普通的一些需求场景,今天就遇到了一种需要经常需要登录远程服务器来部署文件的情况? 但是远程服务器限制了登录人数同时在线2人,每次我想发布新版本到测试服务器时都需要等别人断开连接后才可以。 那么学了这个知识后,我们就可以在我们本地就可以远程操作文件的删除,更新。
也很简单,下面的代码全不管,直接自己手动添加一个网络驱动器(驱动盘随机),填写上需要影射的服务器文件路径,勾选使用其他票据登陆,使用带有操作权限的账号就可以完整服务器文件夹影射到本地网络磁盘的需求了,这时我们就可以通过这个网络驱动器来进行想要的操作了,是不是很棒?!!!如下图:
我要影射的服务器路径为:\\10.0.9.244\Seagll2WebSite\WebApi\YuanXinApi\ 将该路径粘贴到文件夹输入框中即可。
通过代码跨域操作文件:
A-PC端:
1-页面--multiple是控制单张还是多张图片上传
<input id="BusRoute" type="file" class="btn btn-default btn-lg" style="height:34px;padding-top:5px;padding-bottom:5px;" multiple />
2-后台获取图片文件:
HttpFileCollection pcFileColl = HttpContext.Current.Request.Files;
3-保存示例:
#region 创建目录
//完整存储路径
string completeUrl = "";
//相对等级路径
string relativeUrl = ""; //string saveTempPath = "~/Resources/Pic";
//string picUploadPath = HttpContext.Current.Server.MapPath(saveTempPath);
//添加根目录
completeUrl = @"\\10.0.8.52\YuanXinFiles\Office\"; ;
//添加一级目录
string relativeOneUrl = DateTime.Now.Year.ToString();
completeUrl += "\\" + relativeOneUrl;
relativeUrl += "\\" + relativeOneUrl;
if (!Directory.Exists(completeUrl))
{
Directory.CreateDirectory(completeUrl);
}
//添加二级目录
string relativeTwoUrl = DateTime.Now.Month.ToString();
completeUrl += "\\" + relativeTwoUrl;
relativeUrl += "\\" + relativeTwoUrl;
if (!Directory.Exists(completeUrl))
{
Directory.CreateDirectory(completeUrl);
}
#endregion //保存
HttpFileCollection picColl = picModel.PcFileColl;
for (var i = ; i < picColl.Count; i++)
{
HttpPostedFile file = picColl[i];
//保存图片
//保存至指定目录
file.SaveAs(completeUrl + "\\" + fileName);
}
B-APP:
前端页面长什么样不管了,后台拿到的是base64的字符串集合.
1-保存示例:
#region 创建目录
//完整存储路径
string completeUrl = "";
//相对等级路径
string relativeUrl = ""; //string saveTempPath = "~/Resources/Pic";
//string picUploadPath = HttpContext.Current.Server.MapPath(saveTempPath);
//添加根目录
completeUrl = @"\\10.0.8.52\YuanXinFiles\Office\"; ;
//添加一级目录
string relativeOneUrl = DateTime.Now.Year.ToString();
completeUrl += "\\" + relativeOneUrl;
relativeUrl += "\\" + relativeOneUrl;
if (!Directory.Exists(completeUrl))
{
Directory.CreateDirectory(completeUrl);
}
//添加二级目录
string relativeTwoUrl = DateTime.Now.Month.ToString();
completeUrl += "\\" + relativeTwoUrl;
relativeUrl += "\\" + relativeTwoUrl;
if (!Directory.Exists(completeUrl))
{
Directory.CreateDirectory(completeUrl);
}
#endregion //保存
byte[] bytes = Convert.FromBase64String(strPic.picCode);
MemoryStream memStream = new MemoryStream(bytes);
BinaryFormatter binFormatter = new BinaryFormatter();
System.Drawing.Bitmap map = new Bitmap(memStream);
Image image = (Image)map;
string imageName = Guid.NewGuid().ToString("N"); //保存图片
image.Save(completeUrl + "\\" + imageName + "." + strPic.picType); //保存图片
C-跨域保存问题:
跨域的常见场景如下图所示:我们通过电脑的网络影射,连接到所需要的目录,这里添加上拥有权限的人员账号即可访问目标文件夹,那么使用C#代码如何获得访问权限呢?
要获取以上访问权限,需要引用一个类和添加一些简单代码:
1-访问代码:
/// <summary>
/// 通过指定用户执行上次图片操作
/// </summary>
/// <param name="uploadAction"></param>
public void UploadFileByUser(Action uploadAction)
{
//参考类:D:\SourceCode\MCSFramework\02.Develop\MobileWebApp\YuanXin\Services\FileUploadService\Controllers\UploadController.cs
//无法通过权限认证--只能通过外网访问
try
{
var ip = "10.0.8.52";
var domain = "sinooceanland";
var username = ConfigurationManager.AppSettings["uploadUserName"].ToString(); //配置的用户名
var pwd = ConfigurationManager.AppSettings["uploadPassword"].ToString(); //配置的密码
var root = ConfigurationManager.AppSettings["uploadRootPath"].ToString(); //配置的文件根路径 using (NetworkShareAccesser.Access(ip, domain, username, pwd)) //建立连接
{
uploadAction(); //图片保存代码
}
}
catch (System.Exception e)
{ }
}
2-必须类:
public class NetworkShareAccesser : IDisposable
{
private string _remoteUncName;
private string _remoteComputerName; public string RemoteComputerName
{
get
{
return this._remoteComputerName;
}
set
{
this._remoteComputerName = value;
this._remoteUncName = @"\\" + this._remoteComputerName;
}
} public string UserName
{
get;
set;
}
public string Password
{
get;
set;
} #region Consts private const int RESOURCE_CONNECTED = 0x00000001;
private const int RESOURCE_GLOBALNET = 0x00000002;
private const int RESOURCE_REMEMBERED = 0x00000003; private const int RESOURCETYPE_ANY = 0x00000000;
private const int RESOURCETYPE_DISK = 0x00000001;
private const int RESOURCETYPE_PRINT = 0x00000002; private const int RESOURCEDISPLAYTYPE_GENERIC = 0x00000000;
private const int RESOURCEDISPLAYTYPE_DOMAIN = 0x00000001;
private const int RESOURCEDISPLAYTYPE_SERVER = 0x00000002;
private const int RESOURCEDISPLAYTYPE_SHARE = 0x00000003;
private const int RESOURCEDISPLAYTYPE_FILE = 0x00000004;
private const int RESOURCEDISPLAYTYPE_GROUP = 0x00000005; private const int RESOURCEUSAGE_CONNECTABLE = 0x00000001;
private const int RESOURCEUSAGE_CONTAINER = 0x00000002; private const int CONNECT_INTERACTIVE = 0x00000008;
private const int CONNECT_PROMPT = 0x00000010;
private const int CONNECT_REDIRECT = 0x00000080;
private const int CONNECT_UPDATE_PROFILE = 0x00000001;
private const int CONNECT_COMMANDLINE = 0x00000800;
private const int CONNECT_CMD_SAVECRED = 0x00001000; private const int CONNECT_LOCALDRIVE = 0x00000100; #endregion #region Errors private const int NO_ERROR = ; private const int ERROR_ACCESS_DENIED = ;
private const int ERROR_ALREADY_ASSIGNED = ;
private const int ERROR_BAD_DEVICE = ;
private const int ERROR_BAD_NET_NAME = ;
private const int ERROR_BAD_PROVIDER = ;
private const int ERROR_CANCELLED = ;
private const int ERROR_EXTENDED_ERROR = ;
private const int ERROR_INVALID_ADDRESS = ;
private const int ERROR_INVALID_PARAMETER = ;
private const int ERROR_INVALID_PASSWORD = ;
private const int ERROR_MORE_DATA = ;
private const int ERROR_NO_MORE_ITEMS = ;
private const int ERROR_NO_NET_OR_BAD_PATH = ;
private const int ERROR_NO_NETWORK = ; private const int ERROR_BAD_PROFILE = ;
private const int ERROR_CANNOT_OPEN_PROFILE = ;
private const int ERROR_DEVICE_IN_USE = ;
private const int ERROR_NOT_CONNECTED = ;
private const int ERROR_OPEN_FILES = ; #endregion #region PInvoke Signatures [DllImport("Mpr.dll")]
private static extern int WNetUseConnection(
IntPtr hwndOwner,
NETRESOURCE lpNetResource,
string lpPassword,
string lpUserID,
int dwFlags,
string lpAccessName,
string lpBufferSize,
string lpResult
); [DllImport("Mpr.dll")]
private static extern int WNetCancelConnection2(
string lpName,
int dwFlags,
bool fForce
); [StructLayout(LayoutKind.Sequential)]
private class NETRESOURCE
{
public int dwScope = ;
public int dwType = ;
public int dwDisplayType = ;
public int dwUsage = ;
public string lpLocalName = "";
public string lpRemoteName = "";
public string lpComment = "";
public string lpProvider = "";
} #endregion /// <summary>
/// Creates a NetworkShareAccesser for the given computer name. The user will be promted to enter credentials
/// </summary>
/// <param name="remoteComputerName"></param>
/// <returns></returns>
public static NetworkShareAccesser Access(string remoteComputerName)
{
return new NetworkShareAccesser(remoteComputerName);
} /// <summary>
/// Creates a NetworkShareAccesser for the given computer name using the given domain/computer name, username and password
/// </summary>
/// <param name="remoteComputerName"></param>
/// <param name="domainOrComuterName"></param>
/// <param name="userName"></param>
/// <param name="password"></param>
public static NetworkShareAccesser Access(string remoteComputerName, string domainOrComuterName, string userName, string password)
{
return new NetworkShareAccesser(remoteComputerName,
domainOrComuterName + @"\" + userName,
password);
} /// <summary>
/// Creates a NetworkShareAccesser for the given computer name using the given username (format: domainOrComputername\Username) and password
/// </summary>
/// <param name="remoteComputerName"></param>
/// <param name="userName"></param>
/// <param name="password"></param>
public static NetworkShareAccesser Access(string remoteComputerName, string userName, string password)
{
return new NetworkShareAccesser(remoteComputerName,
userName,
password);
} private NetworkShareAccesser(string remoteComputerName)
{
RemoteComputerName = remoteComputerName; this.ConnectToShare(this._remoteUncName, null, null, true);
} private NetworkShareAccesser(string remoteComputerName, string userName, string password)
{
RemoteComputerName = remoteComputerName;
UserName = userName;
Password = password; this.ConnectToShare(this._remoteUncName, this.UserName, this.Password, false);
} private void ConnectToShare(string remoteUnc, string username, string password, bool promptUser)
{
NETRESOURCE nr = new NETRESOURCE
{
dwType = RESOURCETYPE_DISK,
lpRemoteName = remoteUnc
}; int result;
if (promptUser)
{
result = WNetUseConnection(IntPtr.Zero, nr, "", "", CONNECT_INTERACTIVE | CONNECT_PROMPT, null, null, null);
}
else
{
result = WNetUseConnection(IntPtr.Zero, nr, password, username, , null, null, null);
} if (result != NO_ERROR)
{
throw new Win32Exception(result);
}
} private void DisconnectFromShare(string remoteUnc)
{
int result = WNetCancelConnection2(remoteUnc, CONNECT_UPDATE_PROFILE, false);
if (result != NO_ERROR)
{
throw new Win32Exception(result);
}
} /// <summary>
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
/// </summary>
/// <filterpriority></filterpriority>
public void Dispose()
{
this.DisconnectFromShare(this._remoteUncName);
}
}
D--附件类展示(仅供参考):
/// <summary>
/// 附件表
/// </summary>
[ORTableMapping("office.Attachment")]
public class AttachmentModel
{
/// <summary>
/// 主键ID
/// <summary>
[ORFieldMapping("ID", PrimaryKey = true)]
public string ID { get; set; }
/// <summary>
/// 资源ID
/// <summary>
[ORFieldMapping("ResourceID")]
public string ResourceID { get; set; }
/// <summary>
/// 相对路径
/// <summary>
[ORFieldMapping("RelativePath")]
public string RelativePath { get; set; }
/// <summary>
/// 显示路径
/// </summary>
public string ShowPath
{
get
{
string path = AttachmentModelAdapter.Instance.downLoadRootUrl + this.RelativePath + "/" + this.FileName + "." + this.FileType;
return path;
}
}
/// <summary>
/// 文件名称
/// <summary>
[ORFieldMapping("FileName")]
public string FileName { get; set; }
/// <summary>
/// 文件类型
/// <summary>
[ORFieldMapping("FileType")]
public string FileType { get; set; }
/// <summary>
/// 创建时间
/// <summary>
[ORFieldMapping("CreateTime")]
public DateTime CreateTime { get; set; }
/// <summary>
/// 有效性
/// <summary>
[ORFieldMapping("ValidStatus")]
public bool ValidStatus { get; set; }
}
public class AttachmentModelCollection : EditableDataObjectCollectionBase<AttachmentModel> { }
public class AttachmentModelAdapter : BaseAdapter<AttachmentModel, AttachmentModelCollection>
{
public static AttachmentModelAdapter Instance = new AttachmentModelAdapter();
private string ConnectionString = ConnectionNameDefine.YuanXinBusiness;
//上传文件路径(如果路径含有相对路径标记~ 则使用Server获取完整路径,否则获取配置路径)
public string upLoadRootUrl = ConfigurationManager.AppSettings["uploadRootPath"].Contains("~") ? HttpContext.Current.Server.MapPath(ConfigurationManager.AppSettings["uploadRootPath"]) : ConfigurationManager.AppSettings["uploadRootPath"];
//下载文件路径
public string downLoadRootUrl = ConfigurationManager.AppSettings["downLoadRootPath"];
//是否上传到本地服务器
public bool IsUploadLocalService = ConfigurationManager.AppSettings["IsUploadLocalService"] == "true" ? true : false; public AttachmentModelAdapter()
{
BaseConnectionStr = this.ConnectionString;
} /// <summary>
/// 设置用户权限通过远程文件增删
/// </summary>
/// <param name="uploadAction"></param>
private void UploadFileByUser(Action uploadAction)
{
//参考类:D:\SourceCode\MCSFramework\02.Develop\MobileWebApp\YuanXin\Services\FileUploadService\Controllers\UploadController.cs
//无法通过权限认证--只能通过外网访问
try
{
if (IsUploadLocalService == false)
{
var ip = ConfigurationManager.AppSettings["uploadServiceIP"].ToString(); //上传的服务器IP--10.0.8.52
var domain = "sinooceanland";
var username = ConfigurationManager.AppSettings["uploadUserName"].ToString(); //配置的用户名--v-zhaotzh
var pwd = ConfigurationManager.AppSettings["uploadPassword"].ToString(); //配置的密码--pass@123
var root = upLoadRootUrl; //配置的文件根路径--~/Resources/Pic using (NetworkShareAccesser.Access(ip, domain, username, pwd)) //建立连接
{
uploadAction(); //图片保存代码
}
}
else
{
uploadAction(); //图片保存代码
}
}
catch (System.Exception e)
{ }
} #region 文件保存
/// <summary>
/// 保存附件集合
/// </summary>
/// <returns></returns>
private int SaveFileColl(AttachmentModelCollection acoll)
{
StringBuilder sql = new StringBuilder();
acoll.ForEach(ac =>
{
sql.Append(ORMapping.GetInsertSql<AttachmentModel>(ac, TSqlBuilder.Instance, "") + ";");
});
int result = ViewBaseAdapter<AttachmentModel, List<AttachmentModel>>.Instance.RunSQLByTransaction(sql.ToString(), ConnectionNameDefine.YuanXinForDBHelp);
return result;
} /// <summary>
/// 保存图片至服务器及将数据入库
/// </summary>
/// <param name="picModel"></param>
public void SavePicColl(PictureHelp picModel)
{
UploadFileByUser(() =>
{
#region 创建目录
//完整存储路径
string completeUrl = "";
//相对等级路径
string relativeUrl = ""; //添加根目录
completeUrl = upLoadRootUrl;
//添加一级目录
string relativeOneUrl = DateTime.Now.Year.ToString();
completeUrl += "\\" + relativeOneUrl;
relativeUrl += "/" + relativeOneUrl;
if (!Directory.Exists(completeUrl))
{
Directory.CreateDirectory(completeUrl);
}
//添加二级目录
string relativeTwoUrl = DateTime.Now.Month.ToString();
completeUrl += "\\" + relativeTwoUrl;
relativeUrl += "/" + relativeTwoUrl;
if (!Directory.Exists(completeUrl))
{
Directory.CreateDirectory(completeUrl);
}
#endregion AttachmentModelCollection modelColl = new AttachmentModelCollection(); #region 来源于APP
if (picModel.AppPicColl != null && picModel.AppPicColl.Count > )
{
List<AppPicHelp> strPicColl = picModel.AppPicColl; foreach (var strPic in strPicColl)
{
byte[] bytes = Convert.FromBase64String(strPic.picCode);
MemoryStream memStream = new MemoryStream(bytes);
BinaryFormatter binFormatter = new BinaryFormatter();
System.Drawing.Bitmap map = new Bitmap(memStream);
Image image = (Image)map; //保存图片
string imageName = Guid.NewGuid().ToString("N"); //图片重命名
image.Save(completeUrl + "\\" + imageName + "." + strPic.picType); //保存图片 AttachmentModel model = new AttachmentModel()
{
ID = Guid.NewGuid().ToString("N"),
CreateTime = DateTime.Now,
FileName = imageName,
FileType = strPic.picType,
RelativePath = relativeUrl,
ResourceID = picModel.ResourceID,
ValidStatus = true
};
modelColl.Add(model);
}
}
#endregion #region 来源于PC端
//来源于PC端
else if (picModel.PcFileColl != null && picModel.PcFileColl.Count > )
{
HttpFileCollection picColl = picModel.PcFileColl; //入库
for (var i = ; i < picColl.Count; i++)
{
HttpPostedFile file = picColl[i]; string[] oldFileNameList = file.FileName.Split('.');
string fileName = oldFileNameList[] + "_" + DateTime.Now.ToString("HH-mm-ss") + "_" + Guid.NewGuid().ToString("N").Substring(, ) + "." + oldFileNameList[];
string[] newFileNameList = fileName.Split('.'); //保存图片
//保存至指定目录
file.SaveAs(completeUrl + "\\" + fileName); AttachmentModel model = new AttachmentModel
{
ID = System.Guid.NewGuid().ToString("N"),
CreateTime = DateTime.Now,
ValidStatus = true,
FileName = newFileNameList[],
FileType = newFileNameList[],
RelativePath = relativeUrl,
ResourceID = picModel.ResourceID
};
modelColl.Add(model);
}
}
#endregion //图片数据入库
AttachmentModelAdapter.Instance.SaveFileColl(modelColl);
});
}
#endregion /// <summary>
/// 删除会议圈下图片文件及相关数据
/// </summary>
/// <param name="momentID"></param>
public void DelPicColl(string momentID)
{
AttachmentModelCollection coll = AttachmentModelAdapter.Instance.Load(m => m.AppendItem("ResourceID", momentID));
//删除本服务器图片
if (IsUploadLocalService == true)
{
coll.ForEach(c =>
{
File.Delete(c.ShowPath);
});
}
//删除其他服务器图片
else
{
UploadFileByUser(() =>
{
coll.ForEach(c =>
{
File.Delete(c.ShowPath);
});
});
}
//删除数据
Delete(m => m.AppendItem("ResourceID", momentID));
}
}
#region 图片帮助类
public class PictureHelp
{
/// <summary>
/// 资源ID
/// </summary>
public string ResourceID { get; set; }
/// <summary>
/// pc上传图片集合
/// </summary>
public HttpFileCollection PcFileColl { get; set; }
/// <summary>
/// app上传图片集合
/// </summary>
public List<AppPicHelp> AppPicColl { get; set; }
}
public class AppPicHelp
{
/// <summary>
/// base64字节
/// </summary>
public string picCode { get; set; }
/// <summary>
/// 图片类型(jpg/png/...)
/// </summary>
public string picType { get; set; }
}
#endregion
C#--图片上传(PC端和APP)保存及 跨域上传说明的更多相关文章
- Angular4 后台管理系统搭建(10) - 做一个通用的可跨域上传文件的组件
写的很慢,不知不觉这是第十篇了.但是我其他事情太多,只能抽空写下.现在angular4或angular2流行的上传方式是ng2-file-upload.它的功能很强大.但是我没有配置成可以跨域上传的. ...
- 从Ueditor跨域上传,总结的一次跨域上传的爬坑经历
项目内其中一个管理后台需要发布文章,需要一个富文本编辑器,经过一番选择后,最终选择了百度的Ueditor. 由于上传的文件是上传到另一台专门存放图片等静态资源的服务器上面的,所以就涉及到了跨域上传. ...
- 我是如何一步步编码完成万仓网ERP系统的(七)产品库设计 3.品牌图片跨域上传
https://www.cnblogs.com/smh188/p/11533668.html(我是如何一步步编码完成万仓网ERP系统的(一)系统架构) https://www.cnblogs.com/ ...
- html5上传图片(一)一跨域上传
最近开发一个上传图片的模块,传图片的接口不支持跨域上传,并且只支持单张上传,而我们的产品要求要实现多张上传.我搞了一个代理页面,先将图片传到代理页面,然后再通过代理页面传到上传图片接口.虽然这种方式经 ...
- Ueditor1.4.3实现跨域上传到独立文件服务器,完美解决单文件和多文件上传!
再写配置方法之前先吐槽一下网上的各种教程,TM没一个有卵用,一群傻屌不会写就别写,写了就要负责. 百度google搜了半天,全是配置什么document.domain,根域名什么的,我只想对你说: 好 ...
- webuploader 跨域上传demo(还没有写记录一下)
webuploader 跨域上传demo(还没有写记录一下)
- js跨域上传文件 iframe
封装好的jq插件 (function () { var iframe = '<iframe name="jqUploadIframe" style="display ...
- 解决使用elementUI框架el-upload跨域上传时session丢失问题
解决方法一: 1.使用elementUI框架el-upload跨域上传时,后端获取不到cookie,后端接口显示未登录,在添加了 with-credentials="true"后依 ...
- Editor.md解决跨域上传的问题
Editor.md解决跨域上传的问题 编辑 editormd\plugins\image-dialog\image-dialog.js 替换以下代码片段 if (settings.crossDomai ...
随机推荐
- 深入理解javascript的getTime方法
1.理解getTime getTime() 方法返回一个时间的格林威治时间数值. 可以使用这个方法把一个日期时间赋值给另一个Date 对象. 语法: dateObj.getTime() 参数: 无. ...
- webpack学习总结
前言 在还未接触webpack,就有几个疑问: 1. webpack本质上是什么? 2. 跟异步模块加载有关系吗? 3. 可否生成多个文件,一定是一个? 4. 被引用的文件有其他异步加载模块怎么办? ...
- Android—Volley:接收服务端发送的json数据乱码问题解决
new JsonObjectRequest中重写方法parseNetworkResponse,内容如下: /** * 重写此方法不会导致乱码 */ @Override protected Respon ...
- 热修复-Tinker
微信开源,真是喜出望外,必须要去看看啊,比起nuwa来微信好很多,而且github上也有专门的官方文档说明,还有很多资料查询 参考地址:https://github.com/Tencent/tinke ...
- oracle常用函数及示例
学习oracle也有一段时间了,发现oracle中的函数好多,对于做后台的程序猿来说,大把大把的时间还要学习很多其他的新东西,再把这些函数也都记住是不太现实的,所以总结了一下oracle中的一些常用函 ...
- 前端开发小白必学技能—非关系数据库又像关系数据库的MongoDB快速入门命令(2)
今天给大家道个歉,没有及时更新MongoDB快速入门的下篇,最近有点小忙,在此向博友们致歉.下面我将简单地说一下mongdb的一些基本命令以及我们日常开发过程中的一些问题.mongodb可以为我们提供 ...
- Struts的拦截器
Struts的拦截器 1.什么是拦截器 Struts的拦截器和Servlet过滤器类似,在执行Action的execute方法之前,Struts会首先执行Struts.xml中引用的拦截器,在执行完所 ...
- 对一致性Hash算法,Java代码实现的深入研究
一致性Hash算法 关于一致性Hash算法,在我之前的博文中已经有多次提到了,MemCache超详细解读一文中"一致性Hash算法"部分,对于为什么要使用一致性Hash算法.一致性 ...
- Fedora 21 安装 Nvidia 驱动以及失败后的补救方法
在 Linux 桌面系统下玩了这么久,大部分时间都是使用 Ubuntu,偶尔使用一下 Fedora.我的电脑中安装有多个 Linux 发行版,见这里<在同一个硬盘上安装多个Linux发行版及Fe ...
- Web API 入门指南 - 闲话安全
Web API入门指南有些朋友回复问了些安全方面的问题,安全方面可以写的东西实在太多了,这里尽量围绕着Web API的安全性来展开,介绍一些安全的基本概念,常见安全隐患.相关的防御技巧以及Web AP ...