使用 ASP.NET MVC 在 JS 文件中为 jQuery 设置 ajax url
Posted
技术标签:
【中文标题】使用 ASP.NET MVC 在 JS 文件中为 jQuery 设置 ajax url【英文标题】:Setting ajax url for jQuery in JS file using ASP.NET MVC 【发布时间】:2010-09-27 11:01:32 【问题描述】:当前,当对 MVC 操作进行 Ajax 调用时,我的 javascript 在视图中,而不是在它自己的 JS 文件中。
然后很容易做到这一点:
var xhr = $.ajax(
url: '<%= Url.Action("DisplayItem","Home") %>/' + el1.siblings("input:hidden").val(),
data: ajax: "Y" ,
cache: false,
success: function(response) displayMore(response, el1, xhr)
);
...然后在 JS 中使用 Url.Action()
在 ajax 调用中包含 URL 非常简单。如果没有对 URL 进行硬编码,我怎么能移动它自己的 JS 文件?
【问题讨论】:
【参考方案1】:我这样做的方法是在服务器端生成 URL 并使用 html5 data attribute 存储在生成的 HTML 中,例如:(Razor 语法)
<li class='customClass' data-url='@Url.Action("DisplayItems", "Home", new id = Model.Id )'>...</li>
然后你可以使用jQuery attr() 函数来获取url,例如:
$(".customClass").click(function ()
$.ajax(
url: $(this).attr("data-url"),
success: function (data)
// do stuff
);
);
如果您生成 HTML 客户端以响应 AJAX 调用,您可以在 JSON 有效负载中包含相关 URL,并以相同方式填充 data- 属性。
【讨论】:
这应该是第一答案。对于那些在服务器端添加 html 属性的人......data_url
在 html 源代码中转换为 data-url
。
小更新:jQuery 的更高版本支持直接使用data()
函数(例如$(this).data('url')
)访问数据属性。
光滑!将近 4 年后帮助了我
@Valamas-AUS 这是一个很好的答案,可以满足许多情况,但我不确定这是不是最好的答案。我认为生成查找表的想法仍然是一个更好的答案,尽管我不同意上面介绍的实现。我对data-url
方法的问题是它假设每个需要的路由都附加了一个DOM 元素。根据我的经验,情况通常并非如此。
@crush - 没有最好的东西 :) “现代” js 可能会做不同的事情。毫无疑问,有一个框架。【参考方案2】:
这种方式充分利用了 MVC 路由,因此您可以充分利用 MVC 框架。 受到 stusmith 回答的启发。
我在ApplicationController
中有一个针对此 URL 的动态 javascript 的操作:
/application/js
我在这里包含静态文件是因为我只想要一个主 javascript 文件来下载。如果需要,您可以选择只返回动态内容:
/// <summary>
/// Renders out javascript
/// </summary>
/// <returns></returns>
[OutputCache(CacheProfile = "Script")]
[ActionName("js")]
public ContentResult RenderJavascript()
StringBuilder js = new StringBuilder();
// load all my static javascript files
js.AppendLine(IO.File.ReadAllText(Request.MapPath("~/Scripts/rr/cart.js")));
js.AppendLine(";");
// dynamic javascript for lookup tables
js.AppendLine(GetLookupTables());
js.AppendLine(";");
return new ContentResult()
Content = js.ToString(),
ContentType = "application/x-javascript"
;
这是创建查找表的辅助函数。只需为您要使用的每个 RouteUrl 添加一行。
[NonAction]
private string GetLookupTables()
StringBuilder js = new StringBuilder();
// list of keys that correspond to route URLS
var urls = new[]
new key = "updateCart", url = Url.RouteUrl("cart-route", new action = "updatecart" ) ,
new key = "removeItem", url = Url.RouteUrl("cart-route", new action = "removeitem" )
;
// lookup table function
js.AppendLine("// URL Lookuptable");
js.AppendLine("$.url=function(url) ");
js.AppendLine("var lookupTable = " + new JavaScriptSerializer().Serialize(urls.ToDictionary(x=>x.key, x=>x.url)) + ";");
js.AppendLine("return lookupTable[url];");
js.AppendLine("");
return js.ToString();
这会生成以下动态 javascript,它基本上只是一个从任意键到我的操作方法所需的 URL 的查找表:
// URL Lookuptable
$.url=function(url)
var lookupTable = "updateCart":"/rrmvc/store/cart/updatecart","removeItem":"/rrmvc/store/cart/removeitem";
return lookupTable[url];
在 cart.js 中我可以有这样的功能。 请注意,url 参数取自查找表:
var RRStore = ;
RRStore.updateCart = function(sku, qty)
$.ajax(
type: "POST",
url: $.url("updateCart"),
data: "sku=" + sku + "&qty=" + qty,
dataType: "json"
// beforeSend: function (),
// success: function (),
// error: function (),
// complete: function (),
);
return false;
;
我可以从任何地方调用它:
RRStore.updateCart(1001, 5);
这似乎是我能想出的唯一方法,可以让我以干净的方式使用路由。在 javascript 中动态创建 URL 很麻烦,而且很难测试。测试类型可以在这里的某处添加一个层,以方便测试。
【讨论】:
这真是太好了,真的很干净! 请注意,您在此处显示了所有操作方法的路径。确保您对需要安全的操作方法有足够的安全性 - 并且您可能会收到对这些方法的更多爬虫请求(未经验证) 你可以用 robots.txt 文件来反驳? 以疏忽为安全,或以默默无闻为安全,无论如何都不是一个好的策略。即使您没有将所有可用的路由发送到浏览器,也不应该假设它们不能被“发现”。我相信你会同意,但只是想补充一点。【参考方案3】:将 AJAX 调用包装在一个函数中,该函数将 URL(和任何其他数据)作为参数并返回响应。那么在你看来,调用函数而不是直接调用AJAX调用。
function doAjax( url, data, elem, callback )
return $.ajax(
url: url,
data: ajax: data ,
cache: false,
success: function(response) callback(response, elem, xhr);
);
...
<input type='button' value='Go get it' onclick='doAjax( <%= Url.Action ...
我不确定这是否比在页面上而不是在 JS 文件中调用 Ajax 更好,除非您经常使用完全相同的模式。
【讨论】:
这不是我们试图通过连接 document.ready 上的事件来删除的内联 JS 吗??? 您的解决方案在技术上是正确的,但我同意您的看法,这并不是真的更好。 这取决于您要抽象到库函数中的内容。在这种情况下,您并没有抽象出任何业务逻辑,只是隐藏了您正在使用 jquery 的事实【参考方案4】:使用模块模式。
// separate js file
var PAGE_MODULE = (function ()
var url = ,
init = function(url) ... ,
load = function()
$.ajax(
url: url,
...
);
return init: init ;
)();
// calling init goes on the page itself
PAGE_MODULE.init(" %: Url.Action(...) %>");
一般来说,内联 onclick 处理程序不是好的 javascript,因为您使用的是全局函数。
onclick='doAjax(我建议阅读http://jqfundamentals.com/book/index.html#N20D82 以更好地了解模块模式。
【讨论】:
【参考方案5】:这是另一种方式:
在您的母版页中,为内联脚本添加一个区域:
<head>
...
<asp:ContentPlaceHolder runat="server" ID="_inlineScripts" />
...
</head>
然后在Page_Load中,创建一个实用函数:
protected void Page_Load( object sender, EventArgs e )
AddInlineScript( string.Format( "$.url=function(url)return '0'+url;", GetBaseUri() ) );
...
private Uri GetBaseUri()
var requestUrl = Request.Url.AbsoluteUri;
var i = requestUrl.IndexOf( request.Path );
return new Uri( requestUrl.Substring( 0, i ) );
private void AddInlineScript( string content )
var script = new HtmlGenericControl( "script" );
script.Attributes.Add( "type", "text/javascript" );
script.InnerHtml = content;
_inlineScripts.Controls.Add( script );
现在你可以在你的 ajax 中使用这个函数了:
$.ajax(
url: $.url('path/to/my-handler'),
...
);
【讨论】:
-1 用于在 ASP.NET MVC 中使用 PageLoad。虽然可以改用别的东西…… 我必须承认我没有正确阅读这个问题......我认为这是一个 ASP.NET 问题。道歉。以上是关于使用 ASP.NET MVC 在 JS 文件中为 jQuery 设置 ajax url的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 jquery 或 ajax 在 c#/asp.net 中为 MVC 项目更新 razor 部分视图
使用实体框架在 ASP.NET MVC 中为具有一对多关系的数据库播种