경량 Ajax 구성 요소 작성(자세한 그래픽 및 텍스트 설명)
이번에는 경량 Ajax 컴포넌트 작성 방법을 알려드리겠습니다(자세한 설명은 그림과 텍스트로 설명). 경량 Ajax 컴포넌트 작성 시 주의사항은 무엇인가요?
이전 소개를 통해 페이지 객체의 메소드를 실행하기 위한 핵심은 요청에서 매개변수를 얻고 지정된 메소드를 실행하는 프로세스인 리플렉션이라는 것을 알았습니다. 실제로 이는 ASP.NET MVC 프레임워크의 핵심 아이디어와 매우 유사합니다. URL을 구문 분석하고 여기에서 컨트롤러와 작업 이름을 가져온 다음 컨트롤러 개체를 활성화하고 요청에서 작업 매개변수를 가져옵니다. 작업을 실행합니다. 웹 양식 플랫폼에서는 .aspx.cs에 메서드를 작성합니다. 우리가 달성하려는 것은 페이지 개체가 생성되기 전에 지정된 메서드를 실행한 다음 결과를 반환하는 것입니다.
먼저 구현 후 몇 가지 호출 예를 살펴보겠습니다. 이러한 함수는 조합하여 사용할 수도 있습니다.
[AjaxMethod] public void Test1(int index) { //简单调用 } [AjaxMethod] public string Test2(Test test) { return "参数为一个Test实例"; } [AjaxMethod(OutputCache = 20)] public string Test3(int index) { return "输出结果缓存20秒"; } [AjaxMethod(ServerCache = 20)] public string Test4() { return "在服务端缓存20秒"; } [AjaxMethod(SessionState=SessionState.None)] public void Test5() { //Session未被加载 } [AjaxMethod(SessionState = SessionState.ReadOnly)] public void Test6() { //Session只能读不能写 } [AjaxMethod(SessionState = SessionState.ReadWrite)] public void Test7() { //Session可以读写 } [AjaxMethod(IsAsync = true)] public void Test8() { //异步调用 }
우리는 이미 기본 실행 프로세스를 숙지했으며 이제 바로 주제로 이동합니다.
Ajax 규칙
일반적으로 주류 브라우저가 ajax를 사용하여 비동기 요청을 보내는 경우 요청 헤더에는 X-Requested-With:XMLHttpRequest 표시가 포함됩니다. 이 태그를 직접 사용하여 Ajax 요청인지 확인할 수도 있지만 프로젝트에서 다른 구성요소가 서로 영향을 주지 않도록 사용자 정의 요청 헤더를 추가합니다.
internal static class AjaxConfig { /// <summary> /// 请求头Ajax标记键 /// </summary> public const string Key = "AjaxFlag"; /// <summary> /// 请求头Ajax标记值 /// </summary> public const string Value = "XHR"; /// <summary> /// 请求头Ajax方法标记 /// </summary> public const string MethodName = ""; }
http 요청 헤더에 AjaxFlag: XHR이 포함되어 있으면 그것이 우리가 처리하려는 것임을 의미합니다. 또한 http 헤더의 MethodName은 실행하려는 메소드의 이름을 나타냅니다.
AjaxMethodAttribute 마크 속성
마크 속성은 반사에 사용됩니다. 여기서는 필요한 몇 가지 기능을 정의합니다. 우리는 다음을 희망합니다:
1. 세션 상태 구성 가능
2. 비동기 핸들러 지원
3. 캐시 가져오기 지원
4. 서버 측 캐시 지원
정의는 다음과 같으며 태그는 AttributeUsag로 표시됩니다. 메소드에만 사용할 수 있습니다.
/// <summary> /// ajax方法标记属性 /// </summary> [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)] public class AjaxMethodAttribute : Attribute { public AjaxMethodAttribute() { } private SessionState _sessionState = SessionState.None; private int _outputCache = 0; private int _serverCache = 0; private ContentType _contentType = ContentType.Plain; private bool _isUseAsync = false; /// <summary> /// session状态 /// </summary> public SessionState SessionState { get { return _sessionState; } set { _sessionState = value; } } /// <summary> /// 客户端缓存时间,以秒为单位。该标记只对get请求有效 /// </summary> public int OutputCache { get { return _outputCache; } set { _outputCache = value; } } /// <summary> /// 服务端缓存时间,以秒为单位 /// </summary> public int ServerCache { get { return _serverCache; } set { _serverCache = value; } } /// <summary> /// 输出类型(默认为text/plain) /// </summary> public ContentType ContentType { get { return _contentType; } set { _contentType = value; } } /// <summary> /// 使用启用异步处理 /// </summary> public bool IsAsync { get { return _isUseAsync; } set { _isUseAsync = value; } } } /// <summary> /// Session状态 /// </summary> public enum SessionState { None, ReadOnly, ReadWrite } /// <summary> /// 输出内容类型 /// </summary> public enum ContentType { Plain, Html, XML, Javascript, JSON }
다양한 핸들러와 AjaxHandlerFactory
이전 기사에 따르면 특정 핸들러는 주로 비동기식과 비동기식의 두 가지 범주로 나뉘며 이 두 가지 범주에는 세 가지 유형의 세션 상태만 지원됩니다. 읽기(IReadOnlySessionState 인터페이스 구현) 및 읽기 및 쓰기(IRequiresSessionState 인터페이스 구현). IReadOnlySessionState 및 IRequiresSessionState는 단지 표시 인터페이스일 뿐입니다(메서드가 없으면 표시 특성을 사용하여 구현하는 것이 더 합리적입니다). 비동기 처리기는 IHttpAsyncHandler 인터페이스를 구현해야 하며, 이 인터페이스는 IHttpHandler를 구현합니다. Handler의 ProcessRequest 메서드(또는 BeginProcessRequest)는 메서드를 실행하려는 곳입니다. 정의는 다음과 같습니다.
비동기 상태의 핸들러:
//不支持Session internal class SyncAjaxHandler : IHttpHandler { private Page _page; private CacheMethodInfo _cacheMethodInfo; internal SyncAjaxHandler(Page page, CacheMethodInfo cacheMethodInfo) { _page = page; _cacheMethodInfo = cacheMethodInfo; } public void ProcessRequest(HttpContext context) { //执行方法(下面详细介绍) Executor.Execute(_page, context, _cacheMethodInfo); } public bool IsReusable { get { return false; } } public static SyncAjaxHandler CreateHandler(Page page, CacheMethodInfo cacheMethodInfo, SessionState state) { switch (state) { case SessionState.ReadOnly: return new SyncAjaxSessionReadOnlyHandler(page, cacheMethodInfo); case SessionState.ReadWrite: return new SyncAjaxSessionHandler(page, cacheMethodInfo); default: return new SyncAjaxHandler(page, cacheMethodInfo); } } } //支持只读Session internal class SyncAjaxSessionReadOnlyHandler : SyncAjaxHandler, IReadOnlySessionState { internal SyncAjaxSessionReadOnlyHandler(Page page, CacheMethodInfo cacheMethodInfo) : base(page, cacheMethodInfo) { } } //支持读写Session internal class SyncAjaxSessionHandler : SyncAjaxHandler, IRequiresSessionState { internal SyncAjaxSessionHandler(Page page, CacheMethodInfo cacheMethodInfo) : base(page, cacheMethodInfo) { } }
비동기 상태의 핸들러:
//不支持Session internal class ASyncAjaxHandler : IHttpAsyncHandler, IHttpHandler { private Page _page; private CacheMethodInfo _cacheMethodInfo; internal ASyncAjaxHandler(Page page, CacheMethodInfo cacheMethodInfo) { _page = page; _cacheMethodInfo = cacheMethodInfo; } public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData) { //执行方法(下面详细介绍) Action<Page, HttpContext, CacheMethodInfo> action = new Action<Page, HttpContext, CacheMethodInfo>(Executor.Execute); IAsyncResult result = action.BeginInvoke(_page, context, _cacheMethodInfo, cb, action); return result; } public void EndProcessRequest(IAsyncResult result) { Action<Page, HttpContext, CacheMethodInfo> action = result.AsyncState as Action<Page, HttpContext, CacheMethodInfo>; action.EndInvoke(result); } public void ProcessRequest(HttpContext context) { throw new NotImplementedException(); } public bool IsReusable { get { return false; } } public static ASyncAjaxHandler CreateHandler(Page page, CacheMethodInfo cacheMethodInfo, SessionState state) { switch (state) { case SessionState.ReadOnly: return new ASyncAjaxSessionReadOnlyHandler(page, cacheMethodInfo); case SessionState.ReadWrite: return new ASyncAjaxSessionHandler(page, cacheMethodInfo); default: return new ASyncAjaxHandler(page, cacheMethodInfo); } } } //支持只读Session internal class ASyncAjaxSessionReadOnlyHandler : ASyncAjaxHandler, IReadOnlySessionState { internal ASyncAjaxSessionReadOnlyHandler(Page page, CacheMethodInfo cacheMethodInfo) : base(page, cacheMethodInfo) { } } //支持读写Session internal class ASyncAjaxSessionHandler : ASyncAjaxHandler, IRequiresSessionState { internal ASyncAjaxSessionHandler(Page page, CacheMethodInfo cacheMethodInfo) : base(page, cacheMethodInfo) { } }
AjaxHandlerFactory는 요청에 따라 특정 핸들러를 생성하는 데 사용되는 IHandlerFactory 인터페이스를 구현합니다. .config. AjaxHandlerFactory의 GetHandler는 요청을 가로채는 첫 번째 단계입니다. 요청 헤더에 있는 AjaxFlag:XHR을 사용하여 처리해야 하는지 여부를 결정합니다. 그렇다면 핸들러를 생성하고, 그렇지 않으면 일반적인 방법으로 진행합니다. 메서드가 .aspx.cs에 작성되었으므로 요청은 페이지(페이지, IHttpHandler 구현) 유형인 .aspx 접미사로 되어 있습니다. 페이지는 IHandlerFactory 인터페이스도 구현하는 PageHandlerFactory를 통해 생성됩니다. 핸들러를 생성합니다. 따라서 IHttpHandler를 생성하려면 PageHandlerFactory를 사용해야 하지만 PageHandlerFactory의 constructor는 보호된 내부 유형이므로 새 항목을 직접 생성할 수 없으므로 CommonPageHandlerFactory를 통해 상속해야 합니다.
PageHandlerFactory를 통해 페이지를 얻은 후 메소드 이름과 결합하면 리플렉션을 통해 AjaxMethodAttribute 마크 속성을 얻을 수 있습니다. 그런 다음 관련 속성을 기반으로 특정 처리기를 생성합니다. 구체적인 코드는 다음과 같습니다:
internal class CommonPageHandlerFactory : PageHandlerFactory { } internal class AjaxHandlerFactory : IHttpHandlerFactory { public void ReleaseHandler(IHttpHandler handler) { } public IHttpHandler GetHandler(HttpContext context, string requestType, string url, string pathTranslated) { HttpRequest request = context.Request; if (string.Compare(request.Headers[AjaxConfig.Key], AjaxConfig.Value, true) == 0) { //检查函数标记 string methodName = request.Headers[AjaxConfig.MethodName]; if (methodName.IsNullOrEmpty()) { Executor.EndCurrentRequest(context, "方法名称未正确指定!"); return null; } try { CommonPageHandlerFactory ajaxPageHandler = new CommonPageHandlerFactory(); IHttpHandler handler = ajaxPageHandler.GetHandler(context, requestType, url, pathTranslated); Page page = handler as Page; if (page == null) { Executor.EndCurrentRequest(context, "处理程序类型必须是aspx页面!"); return null; } return GetHandler(page, methodName, context); } catch { Executor.EndCurrentRequest(context, url + " 不存在!"); return null; } } if (url.EndsWith(".aspx", StringComparison.CurrentCultureIgnoreCase)) { CommonPageHandlerFactory orgPageHandler = new CommonPageHandlerFactory(); return orgPageHandler.GetHandler(context, requestType, url, pathTranslated); } return null; } /// <summary> /// 获取自定义处理程序 /// </summary> /// <param name="page">处理页面</param> /// <param name="methodName">处理方法</param> /// <param name="context">当前请求</param> private IHttpHandler GetHandler(Page page, string methodName, HttpContext context) { //根据Page和MethodName进行反射,获取标记属性(下面详细介绍) CacheMethodInfo methodInfo = Executor.GetDelegateInfo(page, methodName); if (methodInfo == null) { Executor.EndCurrentRequest(context, "找不到指定的Ajax方法!"); return null; } AjaxMethodAttribute attribute = methodInfo.AjaxMethodAttribute; if (attribute.ServerCache > 0) { //先查找缓存 object data = CacheHelper.TryGetCache(context); if (data != null) { Executor.EndCurrentRequest(context, data); return null; } } if (attribute.IsAsync) { //异步处理程序 return ASyncAjaxHandler.CreateHandler(page, methodInfo, attribute.SessionState); } return SyncAjaxHandler.CreateHandler(page, methodInfo, attribute.SessionState); } }
上面的CacheMethodInfo是用于缓存调用方法的相关信息的,第一篇我们有提到过优化缓存的一些方法,其中就包括缓存+委托。但这里我们并不直接缓存方法的MethodInfo,因为缓存MethodInfo的话,需要通过Invoke去执行,这样的效率比较低。这里我缓存的是方法的委托,该委托的签名为:Func
/// <summary> /// 缓存方法信息 /// </summary> sealed class CacheMethodInfo { /// <summary> /// 方法名称 /// </summary> public string MethodName { get; set; } /// <summary> /// 方法委托 /// </summary> public Func<object, object[], object> Func { get; set; } /// <summary> /// 方法参数 /// </summary> public ParameterInfo[] Parameters { get; set; } /// <summary> /// Ajax标记属性 /// </summary> public AjaxMethodAttribute AjaxMethodAttribute { get; set; } }
核心方法
1. Eexcutor.GetDelegateInfo 获取方法相关信息
该方法用于遍历页面类,获取所有AjaxMethodAttribute标记的方法信息,生成一个CacheMethodInfo对象,包括标记信息、方法名称、参数信息,以及最重要的方法委托。该对象会缓存在一个哈希表中,下次获取时,直接从内存获得。
/// <summary> /// 获取页面标记方法信息 /// </summary> /// <param name="page">页面对象</param> /// <param name="methodName">方法名称</param> internal static CacheMethodInfo GetDelegateInfo(Page page, string methodName) { if (page == null) { throw new ArgumentNullException("page"); } Type type = page.GetType(); //ajaxDelegateTable是一个Hashtable Dictionary<string, CacheMethodInfo> dic = ajaxDelegateTable[type.AssemblyQualifiedName] as Dictionary<string, CacheMethodInfo>; if (dic == null) { dic = new Dictionary<string, CacheMethodInfo>(); //遍历页面的所有MethodInfo IEnumerable<CacheMethodInfo> infos = (from m in type.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static) let ca = m.GetCustomAttributes(typeof(AjaxMethodAttribute), false).FirstOrDefault() where ca != null select new CacheMethodInfo { //方法标记属性 AjaxMethodAttribute = ca as AjaxMethodAttribute, //方法名称 MethodName = m.Name, //方法参数信息 Parameters = m.GetParameters() }); if (infos.IsNullOrEmpty()) { return null; } for (int i = 0, length = infos.Count(); i < length; i++) { CacheMethodInfo cacheMethodInfo = infos.ElementAt(i); string name = cacheMethodInfo.MethodName; MethodInfo methodInfo = type.GetMethod(name); if (!dic.ContainsKey(name)) { //根据MethodInfo获取方法委托 cacheMethodInfo.Func = ReflectionUtil.GetMethodDelegate(methodInfo); dic.Add(name, cacheMethodInfo); } } ajaxDelegateTable[type.AssemblyQualifiedName] = dic; } CacheMethodInfo currentMethodInfo = null; dic.TryGetValue(methodName, out currentMethodInfo); return currentMethodInfo; }
获取方法的委托的是通过一个ReflectionUtil获得的,该类主要用来优化反射,它通过Expression,可以将MethodInfo编译成Func

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

Video Face Swap
완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

오래된 컴퓨터나 저가형 컴퓨터에 새 생명을 불어넣을 완벽한 Linux 배포판을 찾고 계십니까? 그렇다면, 당신은 올바른 장소에 왔습니다. 이 기사에서는 오래되거나 덜 강력한 하드웨어에 맞게 특별히 맞춤화된 경량 Linux 배포판에 대한 최고의 선택 사항 중 일부를 살펴보겠습니다. 그 이면의 동기가 노후화된 장치를 되살리는 것이든 단순히 예산에 맞춰 성능을 극대화하는 것이든 이러한 경량 옵션은 확실히 그 비용에 적합합니다. 경량 Linux 배포판을 선택하는 이유는 무엇입니까? 경량 Linux 배포판을 선택하면 여러 가지 이점이 있습니다. 그 중 첫 번째는 최소한의 시스템 리소스에서 최고의 성능을 얻을 수 있다는 것입니다. 따라서 처리 능력, RAM 및 저장 공간이 제한된 구형 하드웨어에 이상적입니다. 그 외에도 더 많은 리소스를 집약적으로 사용하는 경우

PHP 및 Ajax를 사용하여 자동 완성 제안 엔진 구축: 서버측 스크립트: Ajax 요청을 처리하고 제안을 반환합니다(autocomplete.php). 클라이언트 스크립트: Ajax 요청을 보내고 제안을 표시합니다(autocomplete.js). 실제 사례: HTML 페이지에 스크립트를 포함하고 검색 입력 요소 식별자를 지정합니다.

제목: jQuery AJAX 요청의 403 오류를 해결하는 방법 및 코드 예제 403 오류는 서버가 리소스에 대한 액세스를 금지하는 요청을 의미합니다. 이 오류는 일반적으로 요청에 권한이 없거나 서버에서 거부되기 때문에 발생합니다. jQueryAJAX 요청을 할 때 가끔 이런 상황이 발생합니다. 이 기사에서는 이 문제를 해결하는 방법을 소개하고 코드 예제를 제공합니다. 해결 방법: 권한 확인: 먼저 요청한 URL 주소가 올바른지 확인하고 리소스에 액세스할 수 있는 충분한 권한이 있는지 확인하십시오.

jQuery는 클라이언트 측 개발을 단순화하는 데 사용되는 인기 있는 JavaScript 라이브러리입니다. AJAX는 전체 웹 페이지를 다시 로드하지 않고 비동기 요청을 보내고 서버와 상호 작용하는 기술입니다. 그러나 jQuery를 사용하여 AJAX 요청을 할 때 가끔 403 오류가 발생합니다. 403 오류는 일반적으로 보안 정책이나 권한 문제로 인해 서버 거부 액세스 오류입니다. 이 기사에서는 403 오류가 발생한 jQueryAJAX 요청을 해결하는 방법에 대해 설명합니다.

jQueryAJAX 오류 403 문제를 해결하는 방법은 무엇입니까? 웹 애플리케이션을 개발할 때 jQuery는 종종 비동기 요청을 보내는 데 사용됩니다. 그러나 때때로 jQueryAJAX를 사용할 때 서버에서 액세스가 금지되었음을 나타내는 오류 코드 403이 발생할 수 있습니다. 이는 일반적으로 서버 측 보안 설정으로 인해 발생하지만 문제를 해결하는 방법이 있습니다. 이 기사에서는 jQueryAJAX 오류 403 문제를 해결하는 방법을 소개하고 구체적인 코드 예제를 제공합니다. 1. 만들다

Golang(Go 언어)은 효율적이고 간결하며 동시에 가벼운 프로그래밍 경험을 제공하기 위해 Google에서 개발한 프로그래밍 언어입니다. 동시성 기능이 내장되어 있으며 개발자에게 동시성이 높은 상황에서 제대로 작동할 수 있는 강력한 도구를 제공합니다. 이 기사에서는 Golang이 높은 동시성 처리에 적합한 이유를 살펴보고 설명할 구체적인 코드 예제를 제공합니다. Golang 동시성 모델 Golang은 고루틴과 채널을 기반으로 하는 동시성 모델을 채택합니다. 고로

Ajax를 사용하여 PHP 메소드에서 변수를 얻는 것은 웹 개발의 일반적인 시나리오입니다. Ajax를 통해 데이터를 새로 고치지 않고도 페이지를 동적으로 얻을 수 있습니다. 이 기사에서는 Ajax를 사용하여 PHP 메소드에서 변수를 가져오는 방법을 소개하고 구체적인 코드 예제를 제공합니다. 먼저 Ajax 요청을 처리하고 필요한 변수를 반환하기 위해 PHP 파일을 작성해야 합니다. 다음은 간단한 PHP 파일 getData.php에 대한 샘플 코드입니다.

Ajax(비동기 JavaScript 및 XML)를 사용하면 페이지를 다시 로드하지 않고도 동적 콘텐츠를 추가할 수 있습니다. PHP와 Ajax를 사용하면 제품 목록을 동적으로 로드할 수 있습니다. HTML은 컨테이너 요소가 있는 페이지를 생성하고 Ajax 요청은 로드한 후 요소에 데이터를 추가합니다. JavaScript는 Ajax를 사용하여 XMLHttpRequest를 통해 서버에 요청을 보내 서버에서 JSON 형식의 제품 데이터를 얻습니다. PHP는 MySQL을 사용하여 데이터베이스에서 제품 데이터를 쿼리하고 이를 JSON 형식으로 인코딩합니다. JavaScript는 JSON 데이터를 구문 분석하여 페이지 컨테이너에 표시합니다. 버튼을 클릭하면 제품 목록을 로드하라는 Ajax 요청이 트리거됩니다.
