2013-02-19 39 views
7

我正在開發一個網頁遊戲。作爲遊戲的一部分,您開始使用一些有限的功能,並且在玩遊戲時解鎖更多功能。什麼響應代碼適合這種情況?

例如,你解鎖/fields作爲步驟3中的教程的一部分。但是如果你只是在地址欄中導航到/fields呢?

我試圖找出什麼是最好的狀態代碼與響應。

403由於用戶訪問的頁面,直到他們解鎖禁止似乎理想。
404也是有意義的,因爲頁面在技術上「不存在」,直到它被解鎖並且還阻止用戶能夠分辨不存在的頁面和他們還沒有解鎖的頁面之間的區別。

但在這兩種情況下,我已經有一些用戶使用瀏覽器cacheing的404分之403結果,而不是讓他們即使在解鎖它,除非他們清除緩存後完全訪問頁報告問題。

我想知道如果我應該繼續使用403或404,或者我應該使用一個未使用的4XX代碼(如442自定義statusText),或者甚至開玩笑地發送HTTP/1.1 418 I'm A Teapot以響應用戶在他們不應該在哪裏撥動是。

我需要一個良好的,堅實的理由,爲什麼一個選項應該在他人使用。

+2

我不知道正確的答案,但下面的帖子提供了一些有趣的參數:http://stackoverflow.com/questions/3297048/403-forbidden-vs-401-unauthorized-http-responses – RobJohnson 2013-02-21 16:22:57

+1

爲什麼不到只是重定向到他們被允許在的頁面?也可能顯示彈出窗口,說該功能尚未提供。 – 2013-02-21 22:11:57

+2

順便說一句,'401 Unauthorized'會是一個壞主意,因爲這個狀態碼僅用於HTTP身份驗證,瀏覽器專門處理這個狀態碼。 – nalply 2013-02-22 21:17:57

回答

3

tl; dr409 Conflict將是一個想法,但也許你有緩存問題。在這種情況下,強制重新加載的緩存破壞程序將會起作用。

龍解釋

也許409 Conflict狀態碼纔有意義:

10.4.10 409衝突

請求無法完成,由於與當前狀態的衝突的資源。只有在預期用戶可能能夠解決衝突並重新提交請求的情況下,才允許使用此代碼。響應主體應該包含足夠的信息以供用戶識別衝突的來源。理想情況下,響應實體會爲用戶或用戶代理提供足夠的信息來解決問題;然而,這可能是不可能的,也不是必需的。

衝突最有可能發生以響應PUT請求。例如,如果正在使用版本控制並且包含PUT的實體更改爲與先前(第三方)請求發生衝突的資源發生衝突,則服務器可能會使用409響應來指示它無法完成請求。在這種情況下,響應實體可能會以響應Content-Type定義的格式包含兩個版本之間的差異列表。

這很有意義,因爲資源只有在用戶完成教程後纔可用。在此之前,資源處於「無效」狀態。用戶可以通過完成教程來解決這個衝突。

後來我調查的情況多一點,我發現,魔鬼在細節。讓我們來看看403 Forbidden404 Not Found的規格。

10.4.4 403禁止

服務器理解了請求,但拒絕執行。授權不起作用,請求不應重複。如果請求方法不是HEAD並且服務器希望公開爲什麼請求沒有被滿足,那麼它應該描述在實體中拒絕的原因。當服務器不希望揭示請求被拒絕的原因時,或者沒有其他響應適用時,通常使用此狀態碼。

重要的是規範,«請求不應該重複»。從不重新請求403頁的瀏覽器可能會做正確的事情。然而,讓我們繼續以404:

10.4.5 404未找到

服務器沒有找到任何匹配的請求URI。沒有跡象表明病情是暫時的還是永久性的。

[省略]

現在我們有一個問題!爲什麼你的404頁面會被緩存?如果規範允許它們是臨時的?

也許在您的設置中,您的403和404頁面的緩存配置不正確。如果是這樣,請諮詢this answer on StackOverflow。它給出了關於緩存4xx頁面的詳細答案。

如果你不想用緩存頭很亂,使用所謂的緩存無效,並通過系統的時間是這樣的(假設PHP作爲Web語言):

<a href="/fields?<?php echo time(); ?>">

這產生像/fields?1361948122這樣的URL,每秒都在增加。這是Markus A提出的解決方案的一個變種。

我假設查詢字符串1361948122被您的資源忽略。如果不是,請將查詢字符串參數中的cache-buster傳遞給例如t=1361948122,並確保參數t未被您的資源評估。

2

在的HTTP錯誤代碼的預期目的而言,我肯定會用403 Forbidden去,因爲頁面不存在(404出),但用戶禁止訪問它,現在(和這個限制不是由於資源衝突,如同時修改,但由於用戶的帳戶狀態,即我認爲409也是如此。基於其預期目的的另一個明智的選擇可能是401,但正如他的評論中已經注意到的那樣,此代碼會觸發一些(如果不是全部的話)瀏覽器顯示登錄對話框,因爲這意味着使用標準Web認證機制可以解決問題。所以,這絕對不是您的選擇。

兩件事情似乎在403的描述有點「misfitting」,所以讓我解決這些問題:

  1. 授權不會幫助...:有關HTTP內部授權機制這隻會談協議,旨在區分403與401。此聲明不適用於任何形式的自定義授權或會話狀態管理。
  2. ...請求不應該重複...:請求必須始終在會話上下文中看到,因此如果用戶的會話上下文發生更改(他解鎖某個功能),然後他重試訪問相同的資源,這是一個不同的要求,即沒有違反這一建議。

當然,你也可以定義自己的錯誤代碼,但由於它可能不會在任何官方的方式保留,也不能保證,一些瀏覽器廠商是不會有意或無意地使用完全相同該代碼來觸發特定的(調試)操作。這是不可能的,但不被禁止。

418也可以,但是。 :)

當然,如果您想特別隱藏功能的潛在可用性,您也可以決定使用404,因爲這是不給任何黑暗用戶任何提示的唯一方法。現在

,你的緩存問題:

無論這些狀態代碼(403,404,409,418)應該觸發瀏覽器緩存頁面違背自己的意願比其他任何一個。問題是,許多瀏覽器只是試圖緩存一切就像瘋了一樣,以加快速度。在我看來,歌劇是最糟糕的。我在這些事情上多次拉我的頭髮。它應該可以使用正確的標題設置來處理它,但是我有過瀏覽器或服務器或某個中間代理決定忽略它們並且無論如何都會中斷我的頁面的情況。

到目前爲止我發現的絕對肯定保證重新加載的唯一可靠方法是添加一個虛擬請求參數,如/ fields?t = 29873,其中29873是每個請求所獨有的數字在任何可能相關的時間範圍內。當然,在服務器上,你可以簡單地忽略這個參數。請注意,僅當用戶首次打開頁面時,從1開始並不足以滿足以下請求,因爲瀏覽器可能會跨頁重新加載緩存。

我做我的Web開發中的Java(服務器和使用GWT客戶端),我用這個代碼來生成虛擬的「數字」:

private static final char[] base64chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_.".toCharArray(); 
private static int tagIndex = 0; 

/** 
* Generates a unique 6-character tag string that is guaranteed to not repeat 
* for about 400 days, if this function is, on average, not called more often 
* than twice every millisecond. 
* 
* @return the tag string 
*/ 
public static String nowTag() { 
    int tag = (int) ((System.currentTimeMillis() >>> 5)); // adjust 
    char[] result = new char[6]; 
    result[5] = base64chars[(tagIndex++) & 63]; 
    result[4] = base64chars[tag & 63]; 
    tag >>>= 6; 
    result[3] = base64chars[tag & 63]; 
    tag >>>= 6; 
    result[2] = base64chars[tag & 63]; 
    tag >>>= 6; 
    result[1] = base64chars[tag & 63]; 
    tag >>>= 6; 
    result[0] = base64chars[tag & 63]; 
    return new String(result); 
} 

它使用系統的時鐘結合一個計數器能夠每ms提供約兩個保證唯一值。您可能不需要這種速度,所以您可以隨時更改我標記爲「調整」的>>> 5以符合您的需求。如果你將它增加1,你的利率下降兩倍,你的唯一性時間加倍。因此,例如,如果您將>>> 8代替,則可以每4毫秒生成一個值,並且這些值不應在3200天內重複。當然,如果用戶使用系統時鐘混淆,這種保證值不會重複的情況將會消失。但是,由於這些值不是按順序生成的,所以您很可能不會再次輸入相同的數字。該代碼生成一個6個字符的文本字符串(base64),而不是一個十進制數字,以使URL儘可能短。

希望這會有所幫助。:)

0

我覺得沒有必要拋出一個錯誤代碼,儘管你只是顯示一個類似

你必須等級XX訪問此頁面或有趣的東西像的消息來當你長大後回來

代碼200-OK本身,所以不會有緩存問題,目標也實現了。