jQuery Tips #2
در این پست قصد دارم نحوهی کاربا Cookie را با استفاده از jQuery برسی کنم و در پست بعدی یک مثال عملی را برسی میکنیم.
همانطور که میدانید کوکی یکی از اشیاء بسیار مهم برای نگه داری دادهها در بحث وب میباشد که یک فایل متنی است که سمت Client ذخیره میشود. و ما زمانی که از کتابخانه jQuery استفاده میکنیم خیلی مهم است که بدانیم چگونه باید با Cookieها کار کرد.
برای کار با کوکیها در jQuery باید از Plugin های موجود استفاده کرد . برای ایجاد یک Cookie ابتدا فایل jQuery و سپس این کتابخانه را به صفحه مورد نظر اضافه نموده و کد زیر را برای ایجاد یک کوکی مینویسیم
<script src="jquery-1.7.1.min.js" type="text/javascript"></script> <script src="jquery.cookie.js" type="text/javascript"></script> <script type="text/javascript"> $(function () { $.cookie("TestCookie", "Test Cookie By Mohsen Bahrzadeh "); }); </script>
حال پروژه را اجرا میکنیم. و در تصویر زیر مشاهده میکنید که کوکی ما ایجاد شده است
یکی از آیتمهای بسیار مهم در کوکیها تعریف زمان انقضاء کوکی است برای ست کردن تاریخ از کد زیر استفاده میکنیم
$(function () { $.cookie("TestCookie", "Test Cookie By Mohsen Bahrzadeh ", { expires: 7 }); });
$(function () { alert($.cookie("TestCookie")); });
$(function () { $.cookie("TestCookie", null); });
مشکل: زمانیکه یک AsyncPostback در آپدیت پنلASP.Net Ajax رخ دهد، پس از پایان کار، پلاگین جیکوئری که در حال استفاده از آن بودید و در هنگام بارگذاری اولیه صفحه بسیار خوب کار میکرد، اکنون از کار افتاده است و دیگر جواب نمیدهد.
قبل از شروع، نیاز به یک سری پیش زمینه هست (شاید بر اساس روش استفاده شما از آن پلاگین جیکوئری، مشکل را حل کنند):
الف) رفع تداخل جیکوئری با سایر کتابخانههای مشابه.
ب) آشنایی با jQuery Live جهت بایند رخدادها به عناصری که بعدا به صفحه اضافه خواهند شد.
ج) تزریق اسکریپت به صفحه در حین یک AsyncPostback رخ داده در آپدیت پنل
علت بروز مشکل:
علت رخدادن این مشکل (علاوه بر قسمت الف ذکر شده)، عدم فراخوانی document.ready تعریف شده، جهت بایند مجدد پلاگین jQuery مورد استفاده شما پس از هر AsyncPostback رخ داده در آپدیت پنل ASP.Net Ajax است. راه حل استاندارد جیکوئری هم همان مورد (ب) فوق میباشد، اما ممکن است جهت استفاده از آن نیاز به بازنویسی یک پلاگین موجود خاص وجود داشته باشد، که آنچنان مقرون به صرفه نیست.
مثالی جهت مشاهدهی این مشکل در عمل:
میخواهیم افزونهی Colorize - jQuery Table را به یک گرید ویوو ASP.Net قرار گرفته درون یک آپدیت پنل اعمال کنیم.
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="UpdatePanelTest.aspx.cs"
Inherits="TestJQueryAjax.UpdatePanelTest" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="sm" runat="server">
<Scripts>
<asp:ScriptReference Path="~/js/jquery.js" />
<asp:ScriptReference Path="~/js/jquery.colorize-1.6.0.js" />
</Scripts>
</asp:ScriptManager>
<asp:UpdatePanel ID="uppnl" runat="server">
<ContentTemplate>
<asp:GridView ID="GridView1" runat="server" AllowPaging="True"
OnPageIndexChanging="GridView1_PageIndexChanging">
</asp:GridView>
</ContentTemplate>
</asp:UpdatePanel>
</form>
<script type="text/javascript">
$(document).ready(function() {
$('#<%=GridView1.ClientID %>').colorize();
});
</script>
</body>
</html>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace TestJQueryAjax
{
public partial class UpdatePanelTest : System.Web.UI.Page
{
void BindTo()
{
List<string> rows = new List<string>();
for (int i = 0; i < 1000; i++)
rows.Add(string.Format("row{0}", i));
GridView1.DataSource = rows;
GridView1.DataBind();
}
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
BindTo();
}
}
protected void GridView1_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
GridView1.PageIndex = e.NewPageIndex;
BindTo();
}
}
}
راه حل:
از ویژگیهای ذاتی ASP.Net Ajax باید کمک گرفت برای مثال:
<script type="text/javascript">
$(document).ready(function() {
$('#<%=GridView1.ClientID %>').colorize();
});
function pageLoad(sender, args) {
if (args.get_isPartialLoad()) {
$('#<%=GridView1.ClientID %>').colorize();
}
}
</script>
متد استاندارد pageLoad به صورت خودکار پس از هر AsyncPostback رخ داده در آپدیت پنل ASP.Net Ajax فراخوانی میشود (و همچنین پس از پایان پردازش و بارگذاری اولیه DOM صفحه). در این متد بررسی میکنیم که آیا یک partial postback رخ داده است؟ اگر بله، مجددا عملیات بایند افزونه به گرید را انجام میدهیم و مشکل برطرف خواهد شد.
برای مطالعه بیشتر
- در نمونه بحث جاری کنترل بیشتری بر روی رویدادها خواهید داشت. مثلا قسمت xhr.status == 403 و هدایت کاربر به صفحه لاگین در صورت منقضی شدن اعتبارسنجی آن.
- Ajax.BeginForm برای کار کردن حتما نیاز به submit button داره. در مطلب جاری از یک span هم میتونید استفاده کنید و مشکلی نداره.
- در Ajax.BeginForm آنچنان کنترلی بر روی پردازش نهایی خروجی اکشن متد ندارید. مثلا در اینجا عنوان شد که اگر خروجی JSON بود و اگر دارای فیلد مشخصی با مقدار مشخصی بود نیاز است کار خاصی انجام شود. در حالت jQuery Ajax مستقیم، پردازش JSON سادهتر است.
آشنایی با Bower
Bower چیست؟
مزایا:
- نصب ابزارها و کتابخانهها توسط یک خط فرمان!
- به جای اینکه در سایتهای مختلف ورژن کتابخانهها را پیگیری کنید و update شدن یا نشدن آنها را بررسی نمایید(مثلا آیا jQueryمورد استفاده درپروژه ، آخرین نسخه است؟) ، با استفاده از Bower در کمترین زمان ممکن این کار را انجام دهید.
- نصب آفلاین. وقتی کتابخانه ای برای اولین بار نصب شود کش شده و دفعات بعد برای نصب همان کتابخانه(و البته همان ورژن) از کش استفاده خواهد کرد.(مگر اینکه کاربر صراحتا کش را خالی کرده باشد).
- نصب کتابخانههای وابسته. اگر کتابخانه ای وابسته به کتابخانههای دیگر باشد (مثل وابستگی Twitter Bootstrap به jQuery)، بطور خودکار وابستگیها نیز نصب میگردند.
قبل از نصب باید دو ابزار زیر در سیستم نصب شده باشند:
نصب Bower :
در خط فرمان دستور زیر را اجرا نمایید:
npm install -g bower
نصب کتابخانه ها:
برای نصب کتابخانهها از دستور زیر استفاده میشود:
bower install <package>
bower install angular
bower install jquery
bower install <package>#<version>
bower install jquery#1.7.0
پس از اجرای دستور، در مسیر جاری فولدری به نام bower_components ایجاد شده و کتابخانهها در آن قرار میگیرند.
bower_components/ jquery/ README.md bower.json component.json composer.json jquery-migrate.js jquery-migrate.min.js jquery.js jquery.min.js jquery.min.map package.json
و در نهایت نحوه استفاده:
<script type="text/javascript" src="bower_components/jquery/jquery.js"></script>
جستجو در کتابخانه ها:
Bower امکان جستجو در کتابخانههای ثبت شده را میدهد. مثال:
bower search bootstrap
Search results:
bootstrap git://github.com/twbs/bootstrap.git
angular-bootstrap git://github.com/angular-ui/bootstrap-bower.git
sass-bootstrap git://github.com/jlong/sass-twitter-bootstrap.git
در جهت تکمیل بحث "بررسی امنیتی، حین استفاده از jQuery Ajax"، یک مورد دیگر را هم میتوان اضافه کرد: چگونه صفحهی معروف Add service reference را در VS.NET جهت سرویس WCF خود از کار بیندازیم؟
راه حل آن هم بسیار ساده است اما چون عموما در منابع مرتبط با جملات و کلمات بیش از حد فنی بیان میشود، شاید از دید دور مانده باشد:
اگر WCF Service تولیدی شما تنها قرار است توسط برنامهی Silverlight یا جاوا اسکریپتی موجود در پروژهی جاری مورد استفاده قرار گیرد، باید Meta Data مرتبط با آن سرویس را جهت بالابردن امنیت سیستم، حذف نمود. توسط این Meta Data میتوان ServiceContract ، OperationContract و سایر اطلاعات یک WCF Service را استخراج نمود.
الف) روش غیر فعال کردن متادیتا در یک Ajax enabled WCF Service
به فایل وب کانفیگ برنامه مراجعه کرده و تغییر زیر را اعمال کنید:
...
<behavior name="">
<serviceMetadata httpGetEnabled="false" httpsGetUrl="false" />
...
</behavior>
...
ب) روش غیرفعال کردن متادیتا در یک Silverlight enabled WCF Service
ابتدا قسمت الف را اعمال نموده سپس تغییر زیر را نیز لحاظ نمائید (IMetadataExchange به صورت کامنت درآمده):
<!-- <endpoint address="mex" binding="mexHttpBinding"
contract="IMetadataExchange" /> -->
با این تغییرات ساده، گزینهی Add service reference دیگر قابلیت تشخیص خودکار اطلاعات سرویس شما را نداشته و با یک خطا متوقف خواهد شد:
The HTML document does not contain Web service discovery information.
Metadata contains a reference that cannot be resolved.
سؤال:
1- آیا با این تغییر در عملکرد WCF سرویس ما اخلال ایجاد خواهد شد؟
پاسخ: خیر. تنها Web service discovery information را از کار انداختهایم.
2- در صورت تغییر کدهای WCF Service چه باید کرد؟
پاسخ: اگر امضای متدها و اینترفیسهای تعریف شده تغییری نداشتهاند، لزومی به هیچ نوع تغییری نیست. در غیراینصورت، سریع موارد الف و ب فوق را به حالت اول برگردانده، کلاینت مورد استفاده را به روز کنید، مجددا متادیتا را حذف نمائید.
مرورگرها در آینده مجهز به AI میشن اصلیترین دلیلش هم بحث privacy است؛ حین کار با LLMها مسئله امنیت دادهها موضوع به شدت مهمی است؛ روشهای برای anonymise کردن ورودیهای این LLMها قابلانجام است اما مسئله این است که اگر کانتکست کافی وجود نداشته باشد خروجی به آن اندازهایی که انتظار داریم شاید مفید نباشد. مدتی است گوگل به صورت آزمایشی در حال اضافه کردن امکان استفاده از LLMها (در حال حاضر Gemini Nano) به مرورگر Chrome است. یکی دیگه از مزایای قراردادن LLMها درون مرورگر پاسخگویی سریع به درخواستها میباشد در اینحالت دیگر نیاز به ارسال درخواست به یک Remote LLM کمتر خواهد شد؛ با پائین آمدن latency، کاربران تجربه نزدیکتر به real-time را احساس خواهند کرد. لازم به ذکر است این قابلیت به صورت آزمایشی و فعلاً در حد یک proposal میباشد و فقط در نسخههای Canary و Dev قابل استفاده میباشد.
ASP.NET MVC #21
- محل قرارگیری تمام عناصر رو در صفحه با استفاده از jQuery میشود تغییر داد.
اگر با مفاهیمی مانند Id عناصر و نحوه استفاده از آنها در jQuery آشنایی ندارید، یک دوره مقدماتی در اینباره در سایت موجود است.
بررسی واژه کلیدی static
- همانطور که تاکید کردم فیلد استاتیک و نه متد استاتیک که مشکل همزمانی را ندارد.
- برای jQuery Ajax چون بسیاری از ملاحظاتی که توسط MS Ajax انجام میشود مانند کار با ViewState و ارسال و مدیریت آن صورت نمیگیرد، امکان ایجاد وهلهای از کلاس استاندارد صفحه ASP.Net توسط آن میسر نیست. بنابراین باید این متد را استاتیک تعریف کرد تا وابستگی آنرا از شیء صفحه قطع کرد. به همین جهت jQuery Ajax بسیار بهینهتر از MS Ajax عمل میکند (چون اساسا درکی از ViewState ندارد)
«این کار احتمالا در ASP.NET WebForm کار سختی نیست»
اتفاقا کار سادهای نیست و همین مراحل باید طی شود. ضمن اینکه کار با jquery ajax در آنجا به این یک دستی نیست. نیاز است در code behind فرم، متد وب سرویس مانندی به صورت استاتیک تعریف شود (که خودش سبب میشود تا دسترسی به اعتبار سنجی توکار مبتنی بر فرمها محدود شود) یا اینکه از یک هندلر مجزا بجای یک اکشن متد کمک گرفته شود ... خلاصه خیلی داستان دارد.