Soluciones a problemas extraños en el desarrollo de envíos de formularios iFrame
NET Framework de Microsoft viene con su propio marco Ajax, que lleva el desarrollo tradicional de ASP NET a una nueva era de desarrollo de Ajax NET. Además de introducir el control ScriptManager en la página para registrar scripts del marco Ajax rico en funciones en el cliente, este enorme marco también proporciona muchos controles Ajax potentes, como el famoso UpdatePanel ModalPopupExtender Rating y otros controles. La introducción de controles Ajax, como el famoso UpdatePanel ModalPopupExtender Rating y otros marcos y controles Ajax, ha simplificado enormemente el trabajo de los desarrolladores y ha brindado una nueva experiencia web a los usuarios. Sin embargo, cuando utilizamos scripts proporcionados por marcos complejos, a menudo nos encontramos con problemas de un tipo u otro. Hay muchos problemas que muchos desarrolladores pueden resolver por sí solos. Creo que muchos desarrolladores pueden resolverlo de forma independiente, pero algunos problemas complejos son realmente estresantes.
Originalmente, usar el desarrollo Ajax en MOSS no es una tarea fácil. ¡Quizás los expertos piensen que no es nada! Podemos encontrar muchos artículos en esta área en Google, y los pasos de configuración están escritos con mucho detalle según la experiencia de las personas mayores, siempre que siga cuidadosamente los pasos para configurar el entorno, generalmente no habrá ningún problema. aplicaciones en MOSS Es como una simple página web de Ajax, pero es un poco más problemático de implementar. No quiero explicar en detalle cómo desarrollar Ajax en MOSS. No quiero explicar en detalle cómo desarrollar Ajax en MOSS. Solo quiero hablar sobre un problema muy extraño causado por el marco Ajax en el desarrollo de MOSS hace algún tiempo. Este problema me molestó durante varios días, pero finalmente lo encontré. una alternativa. En cuanto a la solución, si causará otros problemas, los lectores pueden ayudarme a analizarla. Hace un tiempo, escribí un artículo sobre cómo obtener la ruta local de un archivo seleccionado mediante un script en Firefox, que mostraba cómo obtener la ruta local de un archivo mediante javascript al cargarlo desde el cliente. De hecho, en el proceso de carga de archivos real, obtener la ruta del cliente del archivo tiene poca importancia, a menos que necesitemos implementar funciones como la vista previa local de la imagen; de lo contrario, generalmente podemos obtener la ruta del archivo cargado. el método de publicación del formulario.
lt; bodygt; id del formulario = formulario runat = tipo de archivo = archivo /gt; ID del botón= Botón runat= servidor Texto= Botón OnClick= Botón _Clic /gt;lt;/formgt;lt;/bodygt;?
botón vacío protegido _Click(objeto remitente EventArgs e){ archivos HttpFileCollection = Solicitud Archivos; if (files ! = null amp; files Count gt; ) { for (int i = ; i lt; files Count; i ) { // TODO algo }.}} Al enviar la página, establezca el atributo de método de form Establecer para publicar y enctype para datos multipart/form. Una vez enviada la página, el servidor obtendrá la colección de archivos cargados mediante el método Solicitar archivos. Esto es muy simple, ni siquiera necesitamos obtener la ruta del archivo a través de javascript en el lado del cliente, pero hay una limitación: la página debe publicarse en el servidor para obtener el archivo cargado, lo que significa que no podemos obtenerlo. el archivo cargado a través de javascript sin actualizar la página El archivo se envía al servidor. Esto significa que no podemos subir el archivo al servidor sin actualizar la página a través de javascript, esto es lo único que Ajax no puede hacer, pero podemos solucionar este problema usando una técnica más antigua, es decir, en la página Usar un iFrame oculto , luego, antes de enviar la página, oriente el formulario al iFrame oculto y, cuando se envíe la página, actualice el iFrame para enviar la página, evitando así que se actualice toda la página.
De hecho, antes del auge de Ajax, muchas páginas que no se actualizaban se implementaban de esta manera. iFrame no solo puede enviar datos, sino que también evita la actualización general de la página. Después del auge de Ajax, parece que iFrame ya casi no se menciona, con una excepción
y es la carga de archivos. Podemos consultar los sitios web más populares hoy en día, como el correo electrónico, Gmail, etc., todos los cuales utilizan iFrame para cargar archivos sin excepción.
Podemos modificar ligeramente la parte HTML del código anterior para realizar la función de cargar archivos usando iFrame
lt; bodygt lt; form id= form runat= server target= ifu método= post enctype= multipart/ datos del formulario lt; iframe frameborder= id nombre del archivo = ifu lt; /iframegt lt; nombre del archivo = mtfile /gt; ; bodygt; lt; formulario id= formulario runat= destino del servidor= método enc= multipart/formulario ID del botón= Botón runat= servidor Texto= Botón Al hacer clic= Botón _Click /gt;/formgt; El fondo permanece sin cambios, simplemente agregue un atributo de destino al formulario, apuntando al iFrame. Cuando se envía la página, se envía automáticamente el objeto iFrame, no el formulario en sí. Podemos hacer esto cuando hay otros formularios en la página que deben enviarse. Primero, en el evento de cliente del botón de envío, podemos dirigir el formulario al iFrame oculto y devolver True para enviar el formulario. Cuando se envía el iFrame, después de que el servidor haya procesado los datos y los haya guardado, registrará un script para cambiar el destino del formulario en la página principal del iFrame a sí mismo, simulando así el envío del iFrame sin afectar otras funciones en la página. Solo cambiamos el destino del formulario cuando es necesario enviar la página y luego lo volvemos a cambiar después del envío.
Esto parece una buena idea, ¡eche un vistazo al código!
lt; bodygt; id del formulario= formulario runat= nombre enc= multipart/formulario lt; ; ID de entrada = Nombre de archivo = tipo de archivo mt = archivo /gt; asp: ID del botón = Botón onclientclick = Formulario de documento = ifu; ;/formgt;lt;/bodygt;?
Botón vacío protegido _Click(object sender EventArgs e){ HttpFileCollection files = Solicitar archivos; if (files! = null amp; files Count gt; ) { for ( int i = ; i lt; archivos Count; i ) { //TODO algo }.} string script = alerta( { } ); formulario de documento principal de ventana = _self ; cadena Cadena vacía Formato(script ¡Guardado exitosamente! ) verdadero );}
Este método seguirá funcionando incluso si usamos controles Ajax en la página. Cabe señalar que la función de carga de archivos no se puede usar en el control UploadPanel; de lo contrario, la función no funcionará, porque la carga del archivo debe completarse actualizando la página, a menos que usemos iFrame para enviar el formulario.
Si debemos completar la carga del archivo en el control UpdatePanel, debemos configurar la propiedad PostBackTrigger del control UpdatePanel y agregar el control que dispara el evento al PostBackTrigger, por ejemplo
lt;asp:UpdatePanel ID= actualizar runat = modo de actualización del servidor = lt condicional; ContentTemplategt; id de entrada = tipo de archivo mt = archivo /gt: ID del botón = btSave runat = guardar al hacer clic /gt; /ContentTemplategt; lt; Triggersgt; /asp.UpdatePanelgt; esto hará que la página se publique y pierda el significado de el control Panel de actualización. Al colocar un iFrame oculto en la página y modificar dinámicamente el atributo de destino del formulario mediante javascript de la misma manera que antes, enviar el iFrame permitirá que el archivo se cargue en forma similar a Ajax. La carga de archivos funciona de manera similar a Ajax. De hecho, la página también se actualizará, pero usando un iFrame oculto, por lo que el usuario no sentirá nada.
Ya dije esto antes, pero solo quería brindarles una actualización sobre lo que encontré. El trasfondo del problema, ¡ahora quiero entrar en el meollo del problema!
Desarrollar una página en MOSS básicamente no es diferente de una página ASP NET normal, pero lo principal es que encontrará algunos problemas durante la implementación. Entonces, de acuerdo con el método presentado anteriormente, cuando implementé la página escrita en el sitio web y la ejecuté, encontré un problema extraño, es decir, cuando el botón activó el evento por primera vez, el servidor pudo responder correctamente y enviarlo. a través de iFrame, pero desde la segunda vez. Al iniciar por segunda vez, debe esperar más de diez segundos. Pero al comenzar la segunda vez, se necesitan más de 10 segundos para volver a activar el botón. Al principio pensé que el iFrame no había terminado de responder al evento de envío y, por lo tanto, no podía manejar la segunda solicitud, pero luego lo probé estableciendo puntos de interrupción e insertando un script de depuración y descubrí que el iFrame había terminado de responder al evento mientras el botón Todavía no se puede hacer clic.
¿Qué salió mal?
En la era .NET, generalmente encontramos problemas como la falta de eventos para los botones, pero en el entorno .NET, no existe tal problema. Se puede hacer clic en el botón por primera vez. El programa sigue ejecutándose y nadie ha modificado el código, ¡lo que me hace sentir muy extraño! He depurado este problema una y otra vez y he probado muchas cosas diferentes, pero el problema persiste, como mirar otras partes de la página para ver si el uso del método setInterval podría estar provocando que el programa espere (lo cual es imposible)
¡Elimine todos los controles, códigos, etc. que puedan causar problemas! ¡He intentado todo lo que se me ocurre pero esta gran roca no se mueve y estoy muy frustrado!
Dormí en casa durante dos días durante el fin de semana y me preguntaba qué causaba que el botón no se activara. También intenté usar FireBug para rastrear la ejecución del código del cliente del botón en Firefox, pero no encontré nada. .
Utilicé iFrame para enviar el formulario en un proyecto creado localmente y usé javascript para cambiar dinámicamente el atributo de destino del formulario durante el viaje de ida y vuelta de la página al servidor. Sin embargo, descubrí que el evento del botón no se podía activar, lo que indicaba que el problema. no estaba en el código que escribí. Creé una página con la misma funcionalidad en el sitio web de MOSS con unas pocas líneas de código. Después de compilarla, implementarla y activarla, creé otra página con la misma funcionalidad. Creé una página funcional en el sitio web de MOSS con unas pocas líneas de código, compilé, implementé y activé la funcionalidad específica para acceder a la página. Un vistazo rápido a la página muestra que funciona bien, lo que significa que este método funciona bien bajo MOSS y no se ve afectado por el mecanismo MOSS como asumimos.
La página en el entorno de producción es más complicada, excepto por las funciones necesarias y UserControl, toda la página es una página pública heredada del **** público. Toda la página hereda de la página de plantilla del dios público, entonces, ¿el problema radica en la página de plantilla? Miré detenidamente el código en la página de la plantilla e intenté eliminar casi todos los controles en la página de la plantilla, pero el problema aún no se resolvió. Empecé a sudar frío y desperdicié una mañana entera. Las personas que han realizado proyectos MOSS pueden saber mejor que la complejidad de desarrollar un proyecto en MOSS no radica en cómo escribir código, sino en la implementación y depuración del mismo. A menudo se pierde mucho tiempo en esto, sin mencionar que para probar la causa de este problema, tengo que crear un nuevo proyecto. Sin mencionar que tuve que crear una página nueva, volver a implementar el sitio y depurar el código para probar la causa del problema.
En resumen, ya estamos trabajando para solucionar este problema. Después del almuerzo, me ocuparé de este problema. En FireFox, miré el código fuente de la página y, al observar el HTML y los scripts generados, encontré que había dos eventos de script en las etiquetas Body y Form, pero no tenía idea de para qué servían. Tenía curiosidad, así que le pregunté a mi jefe y me dijo que MOSS agregaba automáticamente estos dos eventos al crear una nueva página de plantilla y que nadie los había agregado intencionalmente. _spBodyOnLoadWrapper(); gt; lt; form id= Form runat= server onsubmit= return _spFormOnSubmitWrapper(); post enctype= multipart/form data gt; Finalmente, los eventos de los botones ya no se pierden y se puede hacer clic en ellos sin que dejen de responder. De hecho, el culpable es el método _spFormOnSubmitWrapper en el evento de envío del formulario, y cancelar ese método resuelve el problema.
Pero la cuestión es que, dado que MOSS agrega este evento automáticamente, debe tener un propósito. No podemos simplemente eliminarlo y esperar un error más tarde (aunque no estoy seguro de para qué sirve), así que tendremos que usar FireBug para ver para qué sirve, y le daremos seguimiento.
var _spSuppressFormOnSubmitWrapper= false; función _spFormOnSubmitWrapper(){?if (_spSuppressFormOnSubmitWrapper)?{return true;?}if (_spFormOnSubmitCalled)?{return false;?}if (typeof(_spFormOnSubmit)== función) ?{;var retval=_spFormOnSubmit();;var testval=false;;if (typeof(retval)==typeof(testval) & retval==testval)?{return false;?}?}RestoreToOriginalFormAction() ;? _spFormOnSubmitCalled=true;?return true;} _spFormOnSubmitCalled=true;?Este método activará la hora del lado del servidor siempre que se devuelva verdadero, pero si se devuelve falso, no se activará la hora del lado del servidor. Lo verifiqué una y otra vez. La razón por la que esta función devuelve falso es porque el valor de _spFormOnSubmitCalled es verdadero, por lo que solo necesitamos establecer el valor de esta variable en verdadero. Todo lo que necesitamos hacer es establecer el valor de esta variable en falso para volver a activar el evento del lado del servidor. Ésta es una buena idea. Cambiaré el código ahora y pondré este código en el código de evento del cliente del botón
//aspnetForm es el nombre del cliente del formulario iframeHidden es el nombre del iFrame oculto.
No sé para qué sirven los eventos de formulario que MOSS agrega automáticamente, pero al menos si configuro la variable _spFormOnSubmitCalled en falso, el evento del botón se activa y hace lo que quiero hacer.
Además, dado que actualizaré toda la página después de que se envíe correctamente, no tengo que preocuparme por lo que sucederá si cambio el valor de _spFormOnSubmitCalled. Finalmente, echemos un vistazo al script registrado en el lado del servidor
private const string scriptOK = @ alert( { } ); scriptFailed = @ alert({}); formularios del documento principal de la ventana [aspnetForm] target = _self;; si tiene éxito, actualice toda la página; si falla, cambie el valor del atributo de destino del formulario principal a; _ self; en caso de error, cambia el valor del atributo de destino del formulario principal a _self. Quizás me pregunte por qué agrego # en la ubicación href de la página principal. Esto es principalmente para resolver el problema de que al enviar un formulario a través de iFrame y actualizar toda la página en Firefox, el navegador solo reconoce la URL, por lo que tenemos que cambiarla un poco. Los navegadores solo reconocen las URL, por lo que si cambiamos ligeramente la URL, no se nos pedirá que volvamos a enviar los datos cuando actualicemos la página, siempre y cuando la dirección siga siendo la misma.
Hasta ahora he realizado este cambio en mi código y no sé si tendré algún problema. El propósito de escribir este artículo es doble: uno es registrar el proceso de resolución de este problema y el otro es decirles a los amigos que están desarrollando MOSS que si encuentran el problema de activar eventos en el lado del servidor a través de Ajax, no pueden permitirlo. el servidor da respuesta. El segundo es decirles a los amigos que están desarrollando MOSS que si encuentra el problema de que Ajax no puede activar eventos del lado del servidor, también puede verificar el HTML y los scripts generados por el cliente para descubrir el motivo lishixinzhi/Article/program/net /201311/12554.