2019-10-28 更新
謝謝底下邦友們的幫忙,後來有實作URL Rewriting
以及Post
這兩個方法,都有成功達成目標,之後有時間會再找機會實作Get
或Session
的方法,在此謝過各位~
URL Rewriting
透過註冊額外的路由來控制URL顯示的樣子 (By邦友 YoChen的教學)
網址列長相: https://localhost/report/15713
Post
透過框架去更新網頁內容
網址列長相: https://localhost/report
如下為原本的問題內容
//-------------------------------------------------
如標題所述,我有先看了一些文章,應該與HTTP
的Get
與Post
有關,
我在Controller上寫了程式碼,Index傳入number
參數,再帶到View上,後續的應用在View上,可以先想像成顯示這個參數內容在View上。
網址原本的長相https://localhost/report?number=15713
希望可以變成
(XXXXX的部份表示加工的部份)https://localhost/report?XXXXX
我目前模擬可能的樣子,撰寫了以下的程式碼,但還是不太清楚該如何下手才好,還請各位指導,有個方向也好...
namespace Test.Web.Controllers {
public class ReportController:BaseController {
// GET: Report
public ActionResult Index(string number) {
string reportIdentifier = number;
ViewBag.ReportIdentifier=reportIdentifier;
return View();
}
// POST: Report
[HttpPost]
public ... (string returnUrl){
var result = returnUrl;
return RedirectToLocal(result);
}
}
如同ccutmis大所述,您可以參考URL Rewriting
的作法,在App_Start中的RouteConfig註冊額外路由~
RouteConfig.cs
public static void RegisterRoutes(RouteCollection routes)
{
// 系統Default
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
// 新增的Route Map
routes.MapRoute(
name: "Report", // 名稱
url: "Report/{action}/{number}", // 條件
defaults: new { controller = "Report", action = "Index", number = UrlParameter.Optional } // 參數預設值
);
// 系統Default
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
詳細的說明您可以參考這一篇 MVC下的URL Route 設定
經設定過後,以下的URL將會有相同的結果
New
註: 第一個Url是由於Route Map的Default Action是Index
,所以將Url中的Index省略掉了,不然Url原型應該是第二個
YoChen,不好意思因為有點事,所以過了一陣子才上來看,已嘗試您的作法:
routes.MapRoute(
name: "Report",
url: "Report/{action}/{number}",
defaults: new {
controller = "Report",
action = "Index",
number = UrlParameter.Optional
}
);
我實作完之後,先執行網頁,並調整網址:https://XXXXX/report/index/15713
按Enter逐步執行查看程式執行狀態
不過我發現number
的值並未傳入controller
中,一樣需要給予?number=15713
才會到指定頁面,請問我還可以怎麼調整呢?
anniecat,請先確定RouteConfig.cs中的Route順序
是否正確,由於Route在檢查的時候會由上至下
,遇到符合條件的就會Pass。所以如果您把Default Route
放在您Report Route
之前的話,在遇到Default Route
時就會先Pass了,而不會檢查到Report Route
YoChen,經過您說明的調整以後,已達到您說的預期結果https://YourDomain/report/index/15713
有先上網看了一下Route的部分,不太明白 Default 的部分,因為預設action為Index,所以可以不用告訴是哪一個controller的action,就可以自動導向,網址:https://YourDomain/report?number=15713
但是, Report 的部分,一樣有指定預設的action為Index,網址卻是https://YourDomain/report/index/15713
不能夠為:https://YourDomain/report/15713
(若是controller中都有多個action的狀況下)
請問是為什麼呢?
anniecat,您可以把Route Map
想像成一張參數對照圖
,以Default Route
來舉例
// 系統Default
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
接著說明Route如何判斷,請先記得我們Default Route
的規則
- 參數規則: {controller}/{action}/{id}
- 預設值:
- controller = "Home"
- action = "Index",
- id = UrlParameter.Optional(代表此參數可有可無)
我們帶入以下幾個URL進行測試(前方Domain省略)
URL: Home/Index/123
有controller
,值是Home
有action
,值是Index
有id
,值是123
可能對應的Action
public class HomeController : Controller
{
public ActionResult Index(int id)
{
// Controller: Home
// Action: Index
// id: 123
}
}
URL: Home/Index
有controller
,值是Home
有action
,值是Index
沒有id
,id為UrlParameter.Optional,故可以省略不管
可能對應的Action
public class HomeController : Controller
{
public ActionResult Index()
{
// Controller: Home
// Action: Index
}
}
URL: Home
有controller
,值是Home
沒有action
,補上Default值,值是Index
沒有id
,id為UrlParameter.Optional,故可以省略不管
可能對應的Action
public class HomeController : Controller
{
public ActionResult Index()
{
// Controller: Home
// Action: Index
}
}
URL: {空}
沒有controller
,補上Default值,值是Home
沒有action
,補上Default值,值是Index
沒有id
,id為UrlParameter.Optional,故可以省略不管
可能對應的Action
public class HomeController : Controller
{
public ActionResult Index()
{
// Controller: Home
// Action: Index
}
}
URL: Home?id=123
有controller
,值是Home
沒有action
,補上Default值,值是Index
沒有id
,id為UrlParameter.Optional,故可以省略不管QueryString指定參數為id,值為123
可能對應的Action
public class HomeController : Controller
{
public ActionResult Index(int id)
{
// Controller: Home
// Action: Index
// id: 123
}
}
URL: Home/123
有controller
,值是Home
有action
,值是123
沒有id
,id為UrlParameter.Optional,故可以省略不管
可能對應的Action
public class HomeController : Controller
{
// 找不到123 Action,Error!!
}
以上簡單範例,希望有替您解惑~
當然,如果您想要讓 https://YourDomain/report/15713 能對應到正確值的話,就可以考慮在Route Map中再加入新的Route,e.g.
routes.MapRoute(
name: "Default",
url: "{controller}/{id}",
defaults: new { controller = "Report", action = "Index", id = UrlParameter.Optional }
);
YoChen真的很謝謝你詳盡的解說,我已充分理解,也嘗試出來了!感謝你!
不知道你的用途是什麼
但是我覺得不用花時間在藏這個
因為不管怎麼藏
browser 的 console 都還是看的到
不論你用 Get 或者 Post
重點會在你的後端 code
要網址好看最直接的就是用 Post
如果只是要讓網址欄
看不到get的參數,可以試試把get的連結放在AJAX中。然候網頁透過切版的技巧,每次請求後都只刷新某個特定<div>...</div>
的內容,網址欄
就會一直停在登入頁的網址。
ps. ajax在現在的網站開發十分常見
好的,我看一下~謝謝您~
要用AJAX藏表單參數, 是沒用的
因為凡是走http或https都可以用瀏覽器的外掛抓到參數內容
player, 我這邊強調的是 網址欄 不變動的技巧可透過AJAX達成, 並非是說Ajax可以藏參數內容, 別誤會了!
簡單來說,
只要是前端的東西,
120%無法隱藏,
唯一的方法就是你設一個沒有人看得懂的參數,
不過過了幾個月之後你自己(或接手的人)會想把幾個月前的你給埋了.
也可以考慮用一些框架啦,
不過這東西沒什麼意義就是了.
另外我比較好奇的是,
你的功能都做好了嗎?
我調整了一下發問內容~應該是會去做網址的加工~
你的功能都做好了嗎?
還不完全耶,就是一個功能一個功能的去做XD
我覺得是可以參考 URL重寫 隱藏參數秀出值,例如
原本的網址:
http://www.web3d.url.tw/ITHELP/URL_REWRITE_TEST/index.php?number=HAHA111&type=FUNNY1
用URL重寫後的網址:
http://www.web3d.url.tw/ITHELP/URL_REWRITE_TEST/JUST-A-TEST/HAHA111/FUNNY1/
一般用戶只會看到參數對應的值,不會知道是哪個參數在處理的,如果連值都不想讓人家看到,就把它加密,在接收get變數那一頁再把它解密回來,這樣可行嗎?
anniecat
應該是差不多的概念,不過我跟.NET不熟,技術方面的就幫不上忙了。
網址應該可以設定假的網址...
如果要網址加工也許可以從RouteConfig.cs下手
這個是值用base64加密過的,點進去看可以看到網頁內容用base64還原
http://www.web3d.url.tw/ITHELP/URL_REWRITE_TEST/REPORT/SEFIQUhB/RlVOTlk/
不過我還是比較建議值不用加密的... 處理起來太麻煩了
其實很多人最大的用意就是傳送參數又不想讓人家看到的的矛盾想法。
這邊來說明幾個常用的招式,上面有些已經。
首先是一般要傳送的,一個是參數名,一個是參數值。
參數值來說,一般很少可以被隱藏的。但參數名可以不需要指定的。
典型的方式是採用rw規則。現在只要是mvc架構的大多就是這樣的方式。
如
http://you.com/home/123/456
這樣的域名。實際上運行的東西域名是
http://you.com/home.php?user=123&poassword=456
這樣算是比較基本的方法。可以讓用戶不知道實際的作用為何。
這就是基本的偽裝法。
再來就是後參數傳送法。一般來說這是一種ajax的做法。
也就是將相關值用post的方式來傳送。但不給於實際的參數名。
這算是比較進階的偽裝法。
最後就是加密法及驗証法。
加密法其實也就是很單純的將要傳送的資料做base的方式處理。
讓用戶不清楚你傳啥鬼東東。這會比上面的偽裝法還要好很多。
只是它也有其麻煩性跟限制就是了。
驗証法大多數在asp.net很容易看到。
也就是為了防止用戶修改一些不該給用戶修改的值。
會將其做驗証碼的方式另外存放或是背景處理。
不過這只是防止用戶去修改很重要的資料傳送。
提供下我的公司,傳遞參數的樣子:
onclick=\"GoToPage('XXXEdit/" + XXXPK + "');\"
//說明XXXPK為加密後的主鍵 //修改模式
GoToPage('XXXEdit');
//或是沒有 //新增模式
$.ajax({
url: '@Url.Action("XXX_Edit", Const.XXX)',
data: {
XXX_PK: XXXPK, //新增模式為'',修改模式有數值
XXX_TYPE: $('#XXX').val(),
XXX_UNIT: $('#XXX').val(),
XXX_SUBJECT: $('#XXX').val(),
XXX_CONTENT: $('#XXX').Editor("getText"),
XXX_BEGIN_DATE: $('#XXX').val(),
XXX_END_DATE: $('#XXX').val(),
},
//用AJAX傳參數到後台,然後儲存(刪除也是此作法,參數傳XXXPK就好)
樓主隱藏的時機,是要新增、修改、儲存、刪除?哪一個?
若不是做以上四個功能,而是其他功能(例如:查詢),其實不用隱藏參數!(GOOGLE搜尋關鍵字,也是跑出一堆參數,你會改就直接改網址)
隱藏參數主要隱藏PK,其他參數使用者想改你檔不住。
我可以給你一個替代方案
之前被客戶的弱掃軟體搞得不要不要的
參數的部分必須用session傳值不能直接SHOW在URL上
所以把參數包好後丟到session裡
Session["__SetTrial"] = SetTrial;
//get的時候
if (Session["__SetTrial"]!= null )
{
//原本寫法在URL找
//string SetTrial = Request.QueryString["SetTrial"].ToString();
string SetTrial = Session["__SetTrial"].ToString();
if (SetTrial == "Y")
{
oSec.SetTrial = dt.Rows[0]["SetTrial"].ToString();
oSec.TrialDate = dt.Rows[0]["TrialDate"].ToString();
}
else
{
oSec.SetTrial = "N";
oSec.TrialDate = "";
}
}
Session.Add("SecurityFront", oSec);
順便解決Session Fixation
string newGuid = Guid.NewGuid().ToString();
Session["AuthToken"] = newGuid;
// now create a new cookie with this guid value
Response.Cookies.Add(new HttpCookie("AuthToken", newGuid));
Response.Cookies["AuthToken"].Expires.AddHours(4);
不過放session可能也滿多問題的
如果有敏感資料建議用加密的方法