如何解决是否可以使用 XMLHttpRequest/FormData 对标准 ASP.Net Web 表单进行 HTTP POST?
假设我们有一个 ASP.Net Web 表单 Page.aspx,我们在其中执行以下操作:
<script>
$(document).ready(function () {
// grab the standard ASP.Net form
var form = document.forms['ctl01'];
form.addEventListener("submit",function (event) {
event.preventDefault();
sendData(form);
});
});
function sendData(form) {
const xhr = new XMLHttpRequest();
const fd = new FormData(form);
xhr.addEventListener("load",function (event) {
document.open();
document.write(event.target.response);
document.close();
});
xhr.addEventListener("error",function (event) {
alert('Error!');
});
xhr.open("POST","Page.aspx");
xhr.send(fd);
}
</script>
这个设置的原因是我想利用 XMLHttpRequest 进度事件来 erm,显示一些进度指示,因为回发可能包括需要一些时间上传的文件。
加载事件处理程序运行良好。作为 POST 的结果,我再次获得 Page.aspx 的内容并替换我当前的文档。因此,似乎某种 POST 确实发生了,但是,有一个问题。在 Page.Load() 中,Request.Form 和 Request.Files 集合为空,因此我无法处理表单/文件。
我尝试添加以下标题,但运气不佳:
xhr.setRequestHeader('Content-type','application/x-www-form-urlencoded');
您认为可以使用 XMLHttpRequest/FormData 进行成功的 POST(带有页面接收数据),还是存在一些基本限制来阻止 ASP.Net 页面发生这种情况?
谢谢!
解决方法
好吧,任何 ajax 调用都可以简单地运行一些代码,但是由于网页仍然位于浏览器的客户端,因此控件和页面状态等内容不可用。
所以你不想回帖,但现在你要求回帖? (我很迷惑)。我的意思是,要么你回发整个页面(标准事件回发)。或者您将有问题的控件和内容放到更新面板中,然后仅回发页面的那部分。当整个想法是首先不发送页面时,我没有看到尝试在 ajax 调用中发送“更多”页面的任何优势,对吗?
我的意思是,如果您在 ajax 调用中需要一些额外的值,那么您必须从页面中获取/抓取这些位和部分,并将该信息包含在您的 ajax 调用中。 (可能是一个 json 字符串)。
如果没有回发,那么 viewstate 和所有控件仍然只是坐在浏览器中的用户桌面上。后面的代码,甚至页面类对象+代码此时都超出了范围。只有在回发时整个页面才会传送到服务器 - 运行代码 - 您可以在页面上使用完整的控件,然后整个页面返回到客户端(这在很大程度上意味着 JavaScript 代码必须重新开始!!!
但是,如果您需要一个页面中的一些部分和值并且不想要完整的回发?然后只需将这些部分放入更新面板。例如,您可以在 JavaScript 中执行以下操作:
varMyAspNetButton = docuement.GetElementById("Button1");
varMyAspNetButton.Click();
以上内容将为您拯救世界贫困,而不必连接一堆 js 和 web 方法,因为 js 代码只需点击您的按钮(即在更新面板内)。在这种情况下,当然不会发生整个页面回发,但页面加载和事件实际上会触发 - 这些所谓的“部分”页面回发意味着背后的代码仅限于内部的信息(控件)那个最新的面板。
然而,如前所述,如果你回发,那么浏览器页面现在会传送到服务器 - 这意味着任何 js 代码客户端都是吐司,现在不能运行,因为一个全新的网页副本即将再次传送到客户端 - 这将重新启动您的 js 代码。
如前所述,您可以使用更新面板回发部分页面。在 js 中,您可以使用 js 在该页面上触发“点击”或实际上是 asp.net 控件的 MOST 事件。
但是,然后呢? 您不希望整个页面回传,并且您可能不希望所有控件和整个页面都传送到服务器。但是您又想知道为什么您不能使用或访问带有 ajax 调用的页面上的控件?如前所述,当您进行 ajax 调用时,背后的服务器端代码超出范围和上下文。该网页不存在服务器端。我们不知道用户是否关闭了他们的计算机,或者永远不会在该客户端浏览器和网页中执行任何操作。那个时候的服务器已经失去了该网页的所有知识。所以任何ajax调用都没有使用页面上的控件,甚至也没有使用viewstate。
这往往意味着说使用 ajax 系统上传文件时?好吧,您无法将状态存储在网页服务器端 - 因为该页面在那个时间点并不真正存在。因此,您可以调用一些 Web 方法,并且在上下文中保留某些值的唯一方法是使用 session(),因为这不需要网页或视图状态来运行和工作。
session() 的主要缺点当然是,如果某个用户打开了两个选项卡,甚至打开了两个不同的浏览器?好吧, session() 在这些页面之间是共享的——所以虽然 session() 很棒,但它也在给定用户的所有网页副本之间共享——因此你需要添加代码来分离每个会话“组”值,或者只是希望用户不会有两个页面在运行以进行此类文件上传。
但是要回答你的问题? 您可以使用更新的面板来执行和实现部分页面推送,因此您可以让计时器代码或 js 代码客户端继续运行,因为不会发生完整的页面生命周期。换句话说,您可以使用更新面板控制将网页的哪些部分发送到服务器端。
如果您不使用更新面板,那么您进行的任何 ajax 调用都必须从浏览器端传递数据,因为它仍然只是坐在用户桌面上,而后面的任何代码都无法抓取,也没有伸出手,也没有看到甚至知道该网页存在于客户端。
因此,您可以使用 ajax 调用从网页中传递额外的值,或者您可以使用更新面板,将控件放入其中,然后部分页面回发只会发送并使用该面板中您想要的内容.所以你有两个非常好的选择。
在任何一种情况下(整页回帖)还是部分回帖? 获取对客户端 asp.net 按钮的引用,并触发 .click 事件。我可以假设在 js 中连接各种 _doPostBack,但是使用更新面板和 click() 技巧,然后您可以选择发送多少页面,并且所有这些都非常自动地为您连接起来如果您不使用更新面板来控制它,则可以节省大量工作,您将不得不手动编写和连接这些工作。
所以你会得到那个“部分”页面的回发,在这种情况下,更新面板内的代码和事件可以更新/查看/使用/修改该更新面板中的控件,但除此之外的任何内容更新面板将不会到达服务器。
如果你不使用更新面板,那么任何 ajax 调用都只是 - 直接调用服务器端 - 但网页保持客户端 - 因此加载和任何控件或对象或者实际上,表示该网页的整个类表单对象仍在客户端 - 因此如上所述,没有加载,没有代码可以触摸甚至看到或知道该页面上控件的值,并且如上所述也没有 ViewState。
ajax 调用的整个想法是您不希望也永远不希望页面传送到服务器,然后重新呈现,然后重新发送回客户端。但你需要在这里 100% 清晰:
如果没有页面回发(或带有更新面板的部分页面),则该网页将不再存在于服务器端。网页是无状态的,一旦发生往返(网页到服务器 - 运行背后的代码,页面发送回客户端),那么就服务器而言(以及您的开发人员)该网页已消失并且根本不存在 - 它超出了范围,并且从您的角度(和服务器的角度)来看,该网页在它被发送回客户端的那一刻就不再存在。如前所述,这里唯一可行的例外是 session() 值 - 因为它们不是任何给定网页的一部分。
因此,您必须决定是否要回传部分页面以获取并使用服务器端代码修改某些值。
或者您通过 ajax 调用传递值,然后返回的值可以更新浏览器控件。当然,一旦你最终做到了整页回发,那么后面的代码当然可以看到+使用客户端js代码更改的任何控件-但只能使用整页回发或如上所述的控件来这样做如果我们谈论的是部分页面回发(更新面板),则仅限于更新面板。
您要么必须在 ajax 调用中包含额外的数据,要么考虑使用部分页面回发来发送部分网页,如果您需要修改带有代码的页面部分。或者如前所述,使用 ajax 调用返回信息,然后更新客户端。这里没有真正的中间选择。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。