Asp.Net MVC 使用 Ajax

Ajax

简单来说Ajax是一个无需重新加载整个网页的情况下,可以更新局部页面或数据的技术(异步的发送接收数据,不会干扰当前页面)。

Ajax工作原理

Ajax使浏览器和服务器之间多了一个Ajax引擎作为中间层。通过Ajax请求服务器时,Ajax会自行判断哪些数据是需要提交到服务器,哪些不需要。只有确定需要从服务器读取新数据时,Ajax引擎才会向服务器提交请求。

Ajax几个特点

  1. 不需要提交整个页面就可以更新数据。
  2. 与服务器异步通信。
  3. Ajax请求不能后退,浏览器没有历史记录。
  4. Ajax请求的页面不能加入到收藏夹。

Jquery中的Ajax

JQuery 对 Ajax 做了大量的封装,不需要去考虑浏览器兼容性,使用起来也较为方便。

jquery对Ajax一共有三层封装。

  • 最底层:$.ajax()。

  • 第二层:.load()、$.get()和$.post()。

  • 最高层: $.getScript()和$.getJSON()方法。


$.Ajax()

$.Ajax()是所有Ajax方法中最底层的方法,其他的都是基于$.Ajax()方法的封装,该方法只有一个参数-JQueryAjaxSettings(功能键值对)。

$.Ajax参数JQueryAjaxSettings介绍:

参数 类型 说明
url String 请求的地址
type String 请求方式:POST 或 GET,默认 GET
timeout Number 设置请求超时的时间(毫秒)
data Object或String 发送到服务器的数据,键值对或字符串
dataType String 从服务器返回的数据类型,比如 html、xml、json 等
beforeSend Function 发送请求前可修改 XMLHttpRequest 对象的函数
complete Function 请求完成后调用的回调函数
success Function 请求成功后调用的回调函数,先执行success再执行complete
error Function 请求失败时调用的回调函数,先执行error再执行complete
global Boolean 默认为 true,表示是否触发全局 Ajax
cache Boolean 设置浏览器缓存响应,默认为 true。如果 dataType类型为 script 或 jsonp 则为 false。
content DOM 指定某个元素为与这个请求相关的所有回调函数的上下文。
contentType String 指 定 请 求 内 容 的 类 型 。 默 认 为application/x-www-form-urlencoded。
async Boolean 是否异步处理。默认为 true,false 为同步处理
processData Boolean 默认为 true,数据被处理为 URL 编码格式。如果为 false,则阻止将传入的数据处理为 URL 编码的格式。
dataFilter Function 用来筛选响应数据的回调函数。
ifModified Boolean 默认为 false,不进行头检测。如果为true,进行头检测,当相应内容与上次请求改变时,请求被认为是成功的。
jsonp String 指定一个查询参数名称来覆盖默认的 jsonp 回调参数名 callback。
username String 在 HTTP 认证请求中使用的用户名
password String 在 HTTP 认证请求中使用的密码
scriptCharset String 当远程和本地内容使用不同的字符集时,用来设置 script 和 jsonp 请求所使用的字符集。
xhr Function 用来提供 XHR 实例自定义实现的回调函数
traditional Boolean 默认为 false,不使用传统风格的参数序列化。如为 true,则使用

代码示例:

$('button').click(function(){
$.ajax(
{
type:'post',
url:'test',
data:{
url:'hello',
},
dataType:'json',
success:function(data,stutas,xhr){
alert(data);
},
error:function(xhr, textStatus, data)){
alert(data);
},
complete:function(xhr,textStatus){
alert(textStatus);
}
}
)
});

$.Ajax的回调函数介绍:

  • success

Function( Anything data, String textStatus, jqXHR jqXHR )

请求成功后执行的回调函数。

参数 类型 说明
data anything 从服务器返回的数据,并根据dataType参数类型处理后的数据(默认是json)
textStatus string 描述状态的字符串
jqxhr jqXHR XMLHTTPRequest对象
  • error

Function( jqXHR jqXHR, String textStatus, String errorThrown )

请求失败是执行的回调函数

参数 类型 说明
errorThrown string HTTP状态的文本部分
textStatus string 描述错误信息的字符串
jqxhr jqXHR 描述发生错误类型的一个字符串 和 捕获的异常对象
  • complete

Function( jqXHR jqXHR, String textStatus )

请求完成后执行的回调函数,不管是成功还是失败都执行。

参数 类型 说明
errorThrown string HTTP状态的文本部分
textStatus string 描述请求状态的字符串
jqxhr jqXHR XMLHTTPRequest对象

$.load()

从服务器获取数据并且将返回的HTML代码插入至匹配的元素中。

$('Element').load(url,data,success(responseText,textStatus,XMLHttpRequest))
参数 类型 说明
url string 必须 请求地址
data Json或者string 可选 请求数据 如果是json该load方法是post请求,默认是get请求
success function 当请求成功后执行的回调函数
responseText string 获得字符串形式的响应数据
textStatus string 文本方式返回HTTP状态码
XMLHttpRequest Object xhr对象,有多种属性

$.get()和$.post()

.load()一般在获取静态资源时调用,$.get()$.post()方法在需要和服务器交互数据时调用。

$.get() 方法通过 HTTP GET 请求载入信息。

这是$.ajax GET请求的简写方式。请求成功时可调用回调函数。

$.get(url,data,success(response,status,xhr),dataType)

使用$.get()从服务端获取数据-代码示例

定义model

public class PersonViewModel
{
public int PersonID { get; set; } public string Name { get; set; } public string PhoneNum { get; set; } public bool IsMarried{get;set;} }

定义Controller Action

public class MyAjaxController : Controller
{
public JsonResult PersonList()
{
IList<PersonViewModel> persons = new List<PersonViewModel>();
for (int i = 0; i < 10; i++)
{
persons.Add(new PersonViewModel() { Email = "email" + i, Name = "name", IsMarried = false, PhoneNum = "1234" + i, Home = CityEnum.BJ, Height = i });
}
return Json(persons,JsonRequestBehavior.AllowGet);
}
}

定义View

$.get('@Url.Action("PersonList", "MyAjax")',function (result) {
$.each(result, function (index, person) {
$('#myDiv').append('<p>Id: ' + person.PersonID + '</p>' +
'<p>Name: ' + person.Name + '</p>'); });
}); //在Jquery1.5版本后,新增了一些事件,可以更好的处理不同结果。
$.get('@Url.Action("PersonList", "MyAjax")')
.done(function (data) {
$.each(data, function (index, person) {
$('#myDiv').append('<p>Id: ' + person.PersonID + '</p>' +
'<p>Id: ' + person.Name + '</p>');
});
})
.fail(function (data) {
alert(data);
});

$.post() 方法通过 HTTP POST 请求从服务器载入数据。

$.post(url,data,success(data, textStatus, jqXHR),dataType)

使用$.post()方法向服务端发送数据-代码示例

定义一个Action

 [HttpPost]
public JsonResult ToPersonList(IEnumerable<PersonViewModel> persons)
{
if (persons != null)
return Json(true);
else return Json(false); }

定义一个View

<script>
var results = { persons : [{ "PersonID": "1", "Name": "Manas" },
{ "PersonID": "2", "Name": "Tester" }] };
$.post('@Url.Action("ToPersonList","MyAjax")',results, function (data) {
alert(data)
});;
//同样也可以使用Jquery1.5版本的新的事件
$.post('@Url.Action("ToPersonList","MyAjax")', results)
.done(function (data) {
alert(data);
})
.fail(function (data) {
alert(data);
})
.always(function (data) {
alert(data);
})
</script>

$.get() $.post()方法都是四个参数,前面三个参数和$.load()一样,最后一个参数dataType:服务器返回的数据格式:xml、html、script、json、jsonp和text。只有第一个参数是必须的,其他都可以为空。

$.get() $.post()都是$.ajax()的一个简写封装,都是只能回调success状态,error,和complete不能被回调。但是在jquery1.5版本上,新加了jqXHR.done() (表示成功), jqXHR.fail() (表示错误), 和 jqXHR.always() 事件,可以实现不同状态的回调。


表单序列化

如果我们有一个复杂的表单,一个一个获取表单数据是一个很琐碎的事。jquery提供了一个表单的序列化方法serialize(),会智能的获取指定表单内的所有元素(包括单选框,复选框,下拉列表等)把表单内容序列化为字符串。此外serializeArray()方法可以把数据整合为键值对的json对象。

如果我们需要多次调用$.ajax方法,并且很多参数都相同,可以使用$.ajaxSetup()方法,它会把一些公共的参数预先设置好,不用每次都设置。

$('form input[type=button]').click(function () {
$.ajaxSetup({
type : 'POST',
url : 'test',
data : $('form').serialize()
});
$.ajax({
success : function (response, status, xhr) {
alert(response);
});
});

在使用 data 属性传递数据的时候,如果是以对象形式传递键值对,可以使用$.param()方法将对象转换为字符串键值对格式。

(主要是针对无法直接使用表单序列化方法.serialize(),且传递参数为对象的情况)


MVC中的Ajax使用

Asp.Net MVC中包含了一组Ajax辅助方法。可以用来创建异步执行的表单和指向控制器操作的异步链接。当使用这个辅助方法时,不用编写任何脚本代码来实现程序的异步。该辅助方法依赖于非侵入式MVC的jquery扩展。如果使用这些辅助方法时,需要引入脚本jquery.unbotrusive-ajax.js

(可以在NuGet中获得)

分部渲染

Asp.Net MVC中的分部页面可以是partialPage也可以是含有布局(layout)的完整页面。只是在return的时候返回类型是PartialView

绝大部分情况下,部分页面的请求和完整页面的请求是一样的流程-请求被路由到指定控制器,控制器执行特定的业务逻辑,返回给对应的试图。 我们可以在控制器中使用Request.IsAjax来区别是否是ajax请求,是否是要返回分部试图,还是完整试图。分部试图(return PartialView)是render和返回了该页面的html。但是完整试图(return View)是返回了包括页面资源(css,js)和布局的所有html。

Ajax.Load()

异步加载一个分布页面

  • 定义一个ViewModel
//Model
[Bind(Exclude = "PersonID")]
public class PersonViewModel
{
[ScaffoldColumn(false)]
public int PersonID { get; set; } [Display(Name = "姓名")]
[Required(ErrorMessage = "不能为空")]
public string Name { get; set; } [Display(Name = "手机号")]
[Required(ErrorMessage = "不能为空")]
[DataType(DataType.PhoneNumber)]
public string PhoneNum { get; set; } public bool IsMarried{get;set;}
}
  • 定义主页面View
//Main View:
@{
ViewBag.Title = "主页面";
}
<h2>主页面</h2>
<p>列表详细信息</p>
<div id="partialDiv"></div>
<script>
$('#partialDiv').load('@Url.Action("ListPage", "MyAjax")')
</script>

定义分部页面View

//分部页面
@{
ViewBag.Title = "ListPage";
}
@model IList<WebApp.Models.PersonViewModel>
<h2>分布页</h2>
<table class="table table-striped">
<thead>
@{ WebApp.Models.PersonViewModel p = null;}
<tr>
<th>@Html.LabelFor(m => @p.Email)</th>
<th>@Html.LabelFor(m => @p.Name)</th>
<th>@Html.LabelFor(m => @p.Home)</th>
<th>@Html.LabelFor(m => @p.IsMarried)</th>
<th>@Html.LabelFor(m => @p.Height)</th>
<th>@Html.LabelFor(m => @p.PhoneNum)</th>
@*也可以使用DisplayNameFor来显示表头*@
@*<th>@Html.DisplayNameFor(m => Model[0].Email)</th>
<th>@Html.DisplayNameFor(m => Model[0].Name)</th>
<th>@Html.DisplayNameFor(m => Model[0].IsMarried)</th>
<th>@Html.DisplayNameFor(m => Model[0].Height)</th>
<th>@Html.DisplayNameFor(m => Model[0].PhoneNum)</th>*@
</tr> </thead>
<tbody>
@foreach (var item in Model)
{
<tr>
<td>@item.Email</td>
<td>@item.Name</td>
<td>@item.Home</td>
<td>@item.IsMarried</td>
<td>@item.Height</td>
<td>@item.PhoneNum</td>
</tr>
}
</tbody>
</table>

定义一个Action

//Controller
public class MyAjaxController : Controller
{
//主页面
public ActionResult MainPage()
{ return View();
}
//分部页面
public ActionResult ListPage()
{
IList<PersonViewModel> persons = new List<PersonViewModel>();
for (int i = 0; i < 10; i++)
{
persons.Add(new PersonViewModel() { Email = "email" + i, Name = "name", IsMarried = false, PhoneNum = "1234" + i, Home = CityEnum.BJ, Height = i });
}
if (Request.IsAjaxRequest())
{
return PartialView(persons);
} return View(persons);
}
}

当请求主页面的时候,会把分布页面异步加载到主页面的<div id="partialDiv"></div>


Ajax.ActionLink()

Ajax.ActionLink()辅助方法,可以异步请求加载页面。

//Main view 主页面
@{
ViewBag.Title = "MainPage";
}
<h2>主页面</h2>
<p>列表详细信息</p>
@Ajax.ActionLink("加载详细列表", "ListPage", new AjaxOptions { UpdateTargetId = "partialDiv", InsertionMode = InsertionMode.Replace, HttpMethod = "Get" })
<div id="partialDiv"></div>

Asp.Net MVC 提供了多个AjaxOptions的属性,方法给我们使用,免去了不少js代码。

名称 说明
Confirm 获取或设置在提交请求之前显示在确认窗口中的消息。
HttpMethod 获取或设置 HTTP 请求方法(“Get”或“Post”)。
InsertionModel 获取或设置指定如何将响应插入目标 DOM 元素的模式。插入模式(“InsertAfter”、“InsertBefore”或“Replace”)。 默认值为“Replace”。
LoadingElementDuration 获取或设置一个值(以毫秒为单位),该值控制在显示或隐藏加载元素时的动画持续时间。
LoadingElementId 获取或设置在加载 Ajax 函数时要显示的 HTML 元素的 id 特性。
OnBegin 获取或设置要在更新页面之前立即调用的 JavaScript 函数的名称
OnComplete 获取或设置在实例化响应数据之后但在更新页面之前,要调用的 JavaScript 函数。
OnFailure 获取或设置在页面更新失败时要调用的 JavaScript 函数。
OnSuccess 获取或设置在成功更新页面之后要调用的 JavaScript 函数。
UpdateTargetId 获取或设置要使用服务器响应来更新的 DOM 元素的 ID。
Url 获取或设置要向其发送请求的 URL。

Ajax表单提交

当我们使用jquery的ajax提交表单时,需要在click事件中添加e.preventDefault()或者把<input type="submit" value="提交" />改为<input type="button" value="提交" />。否则会刷新页面。如下代码所示,

<form class="form-horizontal" role="form" method="post" id="myform">
<div>
<label for="i1">第一</label>
<input type="text" name="i1" id="i1" />
</div>
<div>
<label for="i2">第二</label>
<input type="text" name="i2" id="i2" />
</div>
<div>
<label for="i3">第三</label>
<input type="text" name="i3" id="i3" />
</div>
//或者使用<input type="button" value="提交" />,不必再阻止事件的传递了。
<input type="submit" value="提交" />
</form>
<script>
$("input[type=submit]").click(function (e) {
e.preventDefault();//阻止事件传递
$.post("@Url.Action("CheckNameByAjax")", $("#myform").serialize(), function (result) {
alert(result);
});
});
</script>

Asp.Net MVC提供了Ajax的表单辅助方法,可以更简单快速的实现表单的ajax提交。

@using (Ajax.BeginForm("AjaxForm", "MyAjax", new AjaxOptions { HttpMethod = "Post", OnComplete = "foo", OnSuccess = "succ", OnFailure = "fail" }, new { role = "form" }))
{
<div>
<label for="i1">第一</label>
<input type="text" name="i1" id="i1" />
</div>
<div>
<label for="i2">第二</label>
<input type="text" name="i2" id="i2" />
</div>
<div>
<label for="i3">第三</label>
<input type="text" name="i3" id="i3" />
</div>
<input type="submit" value="提交" />
}

Ajax数据验证

在注册有时需要保证用户名或者邮箱唯一或者是否合法,这个验证又必须放在服务端完成。可以使用ajax异步请求,在用户添加完用户名或者邮箱的时候立即在服务端验证并告知用户结果,而不用填完整个表单,再去验证唯一合法性。

  • 定义一个ViewModel
//Model
[Bind(Exclude = "PersonID")]
public class PersonViewModel
{
[ScaffoldColumn(false)]
public int PersonID { get; set; } [Display(Name = "姓名")]
[Required(ErrorMessage = "不能为空")]
public string Name { get; set; } [Display(Name = "手机号")]
[Required(ErrorMessage = "不能为空")]
[DataType(DataType.PhoneNumber)]
public string PhoneNum { get; set; }
}
  • 定义试图View
//view
@model NameSpace.PersonViewModel
<form class="form-horizontal" role="form" method="post" id="myform">
<div>
<div class="form-group">
@Html.LabelFor(m => m.Name, new { @class = "control-label col-md-3" })
<div class="col-md-9">
@Html.TextBoxFor(m => m.Name, new { @class = "form-control" })
@Html.ValidationMessageFor(m => m.Name, "", new { @class = "text-danger" })
</div>
</div>
<div>
<input type="submit" value="提交" class="btn btn-success" id="sure" />
</div>
</div>
</form>
<script>
$("#Name").change(function () {
$.ajax({
url: "@Url.Action("CheckUserName")",
type: "post",
data: { Name: $("#Name").val() },
dataType: "JSON",
success: function (response, stutas, xhr) {
alert(response+status + xhr.statusText);
},
error: function (xhr, stutas, response) {
alert(response + status + xhr.statusText);
},
complete: function (data) {
alert(data.status+data);
},
});
});
</script>
  • 定义一个Action校验用户名的唯一和合法性
[HttpPost]
//参数一定要和ViewModel的属性名称一致
public JsonResult CheckUserName(string Name)
{
bool result = true;
if (Name == "admin")
{
result = false;
}
return Json(result);
}

至此我们实现了Ajax的用户名唯一性和合法性的校验。但是 Asp.Net MVC 提供了一个更简单的方法,可以用更少的代码实现一样的功能

  • 在属性上添加[Remote("MethodName", "ControllerName")]特性

该特性允许客户端调用服务端的方法。

修改Model

   [Bind(Exclude = "PersonID")]
public class PersonViewModel
{
[ScaffoldColumn(false)]
public int PersonID { get; set; } [Display(Name = "姓名")]
//添加Remote特性
[Remote("CheckUserName", "ControllerName",ErrorMessage="用户名已存在")]
[Required(ErrorMessage = "不能为空")]
public string Name { get; set; } [Display(Name = "手机号")]
[Required(ErrorMessage = "不能为空")]
[DataType(DataType.PhoneNumber)]
public string PhoneNum { get; set; }
}

我们只需添加一个Remote特性就可以实现用户名的服务端验证。节省了js的代码。

  • 修改Action

Asp.Net MVC默认是不允许Get请求Json(防止Json被劫持)。所以如果你需要Get请求Json。必须添加JsonRequestBehavior.AllowGet。且该数据不那么重要。

//Action
public JsonResult CheckUserName(string Name)
{
//参数一定要和属性名称一致
bool result = true;
if (Name == "admin")
{
result = false;
}
//添加JsonRequestBehavior.AllowGet
return Json(result, JsonRequestBehavior.AllowGet);
}

Asp.Net MVC Ajax辅助方法可以让我们更简便的使用Ajax。但是也要理解本身Ajajx的请求。


如有不对,请多多指教。


参考资料:

Asp.Net MVC 使用 Ajax的更多相关文章

  1. ASP.NET MVC 实现AJAX跨域请求方法《1》

    ASP.NET MVC 实现AJAX跨域请求的两种方法 通常发送AJAX请求都是在本域内完成的,也就是向本域内的某个URL发送请求,完成部分页面的刷新.但有的时候需要向其它域发送AJAX请求,完成数据 ...

  2. asp.net mvc 使用ajax请求 控制器 (PartialViewResult)分部的action,得到一个分部视图(PartialView)的HTML,进行渲染

    在asp.net mvc 使用ajax请求获取数据的时候,我们一般是返回json或者xml,然后解析这些数据进行渲染,这样会比较麻烦,可以请求一个 分部action,返回一个分部视图 直接可以渲染,不 ...

  3. 在Asp.Net MVC中用Ajax回调后台方法

    在Asp.Net MVC中用Ajax回调后台方法基本格式: var operData = ...; //传递的参数(action中定义的) var type = ...; //传递的参数(action ...

  4. [代码示例]用Fine Uploader+ASP.NET MVC实现ajax文件上传

    原文 [代码示例]用Fine Uploader+ASP.NET MVC实现ajax文件上传 Fine Uploader(http://fineuploader.com/)是一个实现 ajax 上传文件 ...

  5. Asp.Net MVC Unobtrusive Ajax

    1.   Unobtrusive JavaScript介绍 说到Unobtrusive Ajax,就要谈谈UnobtrusiveJavaScript了,所谓Unobtrusive JavaScript ...

  6. ASP.NET MVC之Ajax如影随行

    一.Ajax的前世今生 我一直觉得google是一家牛逼的公司,为什么这样说呢?<舌尖上的中国>大家都看了,那些美食估计你是百看不厌,但是里边我觉得其实也有这样的一个哲学:关于食材,对于种 ...

  7. ASP.NET MVC 实现 AJAX 跨域请求

    ASP.NET MVC 实现AJAX跨域请求的两种方法 和大家分享下Ajax 跨域的经验,之前也找了好多资料,但是都不行,后来看到个可行的修改了并测试下 果然OK了   希望对大家有所帮助! 通常发送 ...

  8. ASP.NET MVC 学习笔记-7.自定义配置信息 ASP.NET MVC 学习笔记-6.异步控制器 ASP.NET MVC 学习笔记-5.Controller与View的数据传递 ASP.NET MVC 学习笔记-4.ASP.NET MVC中Ajax的应用 ASP.NET MVC 学习笔记-3.面向对象设计原则

    ASP.NET MVC 学习笔记-7.自定义配置信息   ASP.NET程序中的web.config文件中,在appSettings这个配置节中能够保存一些配置,比如, 1 <appSettin ...

  9. Asp.net MVC 中Ajax的使用 [分享]

    文章转自 http://www.huiyoumi.wang/upload/forum.php?mod=viewthread&tid=75&extra= Asp.net MVC 抛弃了A ...

随机推荐

  1. JavaWeb(四)EL表达式

    前言 前面详细的说明了什么是JSP和它的一些元素,这篇给大家介绍一下的是EL表达式. 用EL表达式,能更好的使用JSP中的各种内置对象和作用域. 楼主作为大四狗马上要出去面试了,内心很紧张!!! 一. ...

  2. less使用ch1--认识语法

    @charset "utf-8"; //注释------------------------------ /*我是可以被编译出来的*/ //不能被编译出来 //变量-------- ...

  3. Vue 爬坑之路(六)—— 使用 Vuex + axios 发送请求

    Vue 原本有一个官方推荐的 ajax 插件 vue-resource,但是自从 Vue 更新到 2.0 之后,官方就不再更新 vue-resource 目前主流的 Vue 项目,都选择 axios ...

  4. Weave Scope 容器地图 - 每天5分钟玩转 Docker 容器技术(80)

    Weave Scope 的最大特点是会自动生成一张 Docker 容器地图,让我们能够直观地理解.监控和控制容器.千言万语不及一张图,先感受一下. 下面开始实践 Weave Scope. 安装 执行如 ...

  5. 大概是:整数划分||DP||母函数||递推

    整数划分问题 整数划分是一个经典的问题. Input 每组输入是两个整数n和k.(1 <= n <= 50, 1 <= k <= n) Output 对于每组输入,请输出六行. ...

  6. asp.net中使用Global.asax文件中添加应用出错代码,写入系统日志文件或数据库

    void Application_Error(object sender, EventArgs e) { // 在出现未处理的错误时运行的代码 Exception objErr = Server.Ge ...

  7. JS获取fileupload文件全路径

    来自:http://hi.baidu.com/libos88/item/c61ab8bae472afe34ec7fdfb 最近在写个小网站,用到了fileupload控件来上传文件.因为程序的某些需要 ...

  8. WPF 快捷键读写txt

    因为git提交需要写这次做的,所以我想弄个东西来帮我写 WPF可以使用快捷键,快捷键主要使用InputBindings,WPF读写文件很简单 我每次都要写 第一句标题 之后就是我写的修改 然后加上我名 ...

  9. checkbox插件

    1.全选或者全不选 首先判断全选或全不选checkbox是否被选中. 如果被选中,则为每个选项checkbox设置obj.checked='checked'; 如果未被选中,则为每个选项checkbo ...

  10. 南天PR2、PR2E驱动下载,xp,win7,win8,win8.1,win10 32位64位驱动下载安装教程

    家里开淘宝店,有个针式打印机驱动.电脑各种换系统,为了装这个驱动可是废了不小的劲.不敢独享,所以现在把各种驱动以及安装教程分享出来. 注意: 打印机在开机状态下,电脑在开机状态下,不要插拔连接线!!! ...