2012-06-11 37 views
10

我需要檢測用戶的國家,但我試圖避免整個調用外部服務來獲取基於IP或內部數據庫的位置。我需要使這個服務真正響應,並且需要幾乎半秒的時間來查詢任何外部服務,所以我試圖避免這種情況。對於這種方法,任何對數據庫的調用都會很昂貴。我需要頁面在20ms內響應。用於檢測國家的accept_language的準確性

我正在考慮根據Accept_language標題獲取國家區域設置。

我的問題是。有誰知道這可能有多準確?我知道國家並不總是存在,或者用戶可能會更改默認語言,或者使用他們的電腦出現在不同的國家。

有沒有人有以前的經驗或有沒有任何文檔(我找不到一個googling或在W3頁),指定使用這種方法的準確度或錯誤的百分比?

+4

語言⇏國家。閱讀[接受語言用於區域設置](http://www.w3.org/International/questions/qa-accept-lang-locales)。 – Gumbo

+0

已經閱讀過。我要求接受語言方法的%準確性作爲語言環境。並不意味着這將始終有效。 – Martin

回答

8
  • 通過檢測其語言設置的用戶國僅僅是一個壞愚蠢想法。我來自德國,我知道很多人使用他們的瀏覽器/手機或操作系統的其他語言,然後是德語。我知道有幾種交付服務檢查瀏覽器傳輸的語言,如果它不是德語,則不工作。猜猜我在哪裏再次下令。
  • 簡單地通過IP檢測語言。有幾項(甚至是免費的)服務可以將知識產權轉化爲一個國家。
    例如:http://www.maxmind.com/app/geolite。他們確實有一個Web API,一個可以安裝的服務器,或者只是抓住整個數據庫並自行實施。此外,各種網絡服務器還有大量的模塊/助手,不需要任何廣泛的編碼。 (請參閱:Apache的http://www.maxmind.com/app/mod_geoip,這會將訪問者的國家作爲HTTP標頭嵌入。)
    數據庫結果被緩存,並且應該足夠快以滿足您的需要。 20ms是非常快的,如果你一直認爲所有的時間浪費了包裹到服務器,然後整個返回;-)
+2

使用瀏覽器語言是一個非常簡單的實現,不需要花費,也不需要定期更新。 IP檢測也可以完全關閉,特別是「輕」Maxmind數據庫的目的是不準確的,所以當它們關閉時,如果它們停留在同一大陸上,你很幸運。許多德國移動IP在俄羅斯註冊。 ;-)我發現這個頁面尋找一些硬性統計數據,因爲我覺得瀏覽器語言的國家部分可能對預先選擇表單中的國家等用戶仍然可以更正錯誤的事情足夠好。 – Someone

2

我只能推薦你使用本地數據庫。自5年或更長時間以來,我使用了以下免費數據庫。只需下載zip。在加載你的數據庫之前,可能你需要將CVS轉換爲mysql數據,但這很容易。

http://ip-to-country.webhosting.info/node/view/6

會定期更新。它比任何服務器/瀏覽器配置都更準確。

基於php的指南在http://ip-to-country.webhosting.info/node/view/118中使用它。這很容易!

編輯:好的,我剛纔看到了(最後更新於2010年12月14日)。是你......

+0

你說得對,這是一個更好的方法。然而,我仍然在考慮避免對db的調用。這將需要更多的硬件和更多的成本,這是我試圖避免這種情況,因爲它是大量的流量(數百萬/天)。 – Martin

+0

巨大的流量值得所需的hw,我認爲... –

0

用戶@TheHippo是完全正確的。使用Accept-Language HTTP信息對於獲取用戶的國家來說真的不可靠。雖然它沒有速度優勢,因爲它不依賴於外部服務來從IP跟蹤國家。當geoIP類型的服務不可用或者它們向您提供您的網站未呈現或用戶無法訪問的國家/地區時,您可以嘗試將其用作後端服務。

當geoIP類型服務的結果不滿足時,我使用這個函數作爲後端服務。爲此,請檢查documentation

//accept_language may be for example "pt" or "pt-PT" or  
 
//"pt-PT,pt;q=0.9,en;q=0.8,en-GB;q=0.7,de-DE;q=0.6,de;q=0.5,fr-FR;q=0.4,fr;q=0.3,es;q=0.2" 
 
var getCountryFromHTTP = function (accept_language){ 
 

 
    var CC; //Country Code 
 

 
    //in some cases like "fr" or "hu" the language and the country codes are the same 
 
    if (accept_language.length === 2){ 
 
     CC = accept_language.toUpperCase(); 
 
    } 
 
    //get "PT" out of "pt-PT" 
 
    else if (accept_language.length === 5){   
 
     CC = accept_language.substring(3, 5); 
 
    } 
 
    //ex: "pt-PT,pt;q=0.9,en;q=0.8,en-GB;q=0.7,de-DE;q=0.6,de;q=0.5,fr-FR;q=0.4,fr;q=0.3,es;q=0.2" 
 
    //gets the first two capial letters that fit into 2-letter ISO country code 
 
    else if (accept_language.length > 5) { 
 
     var substr; 
 
     for (var i=0; i+2<accept_language.length; i++){ 
 
      substr = accept_language.substring(i, i+2); 
 
      if (isoCountries.hasOwnProperty(substr)){ 
 
       return substr; 
 
      }    
 
     } 
 
    } 
 

 
    if (isoCountries.hasOwnProperty(CC)){ 
 
     return CC; 
 
    } 
 

 
    return false; 
 
}; 
 

 
//2-letter ISO Country Codes 
 
var isoCountries = { 
 
    'AF' : 'Afghanistan', 
 
    'AX' : 'Aland Islands', 
 
    'AL' : 'Albania', 
 
    'DZ' : 'Algeria', 
 
    'AS' : 'American Samoa', 
 
    'AD' : 'Andorra', 
 
    'AO' : 'Angola', 
 
    'AI' : 'Anguilla', 
 
    'AQ' : 'Antarctica', 
 
    'AG' : 'Antigua And Barbuda', 
 
    'AR' : 'Argentina', 
 
    'AM' : 'Armenia', 
 
    'AW' : 'Aruba', 
 
    'AU' : 'Australia', 
 
    'AT' : 'Austria', 
 
    'AZ' : 'Azerbaijan', 
 
    'BS' : 'Bahamas', 
 
    'BH' : 'Bahrain', 
 
    'BD' : 'Bangladesh', 
 
    'BB' : 'Barbados', 
 
    'BY' : 'Belarus', 
 
    'BE' : 'Belgium', 
 
    'BZ' : 'Belize', 
 
    'BJ' : 'Benin', 
 
    'BM' : 'Bermuda', 
 
    'BT' : 'Bhutan', 
 
    'BO' : 'Bolivia', 
 
    'BA' : 'Bosnia And Herzegovina', 
 
    'BW' : 'Botswana', 
 
    'BV' : 'Bouvet Island', 
 
    'BR' : 'Brazil', 
 
    'IO' : 'British Indian Ocean Territory', 
 
    'BN' : 'Brunei Darussalam', 
 
    'BG' : 'Bulgaria', 
 
    'BF' : 'Burkina Faso', 
 
    'BI' : 'Burundi', 
 
    'KH' : 'Cambodia', 
 
    'CM' : 'Cameroon', 
 
    'CA' : 'Canada', 
 
    'CV' : 'Cape Verde', 
 
    'KY' : 'Cayman Islands', 
 
    'CF' : 'Central African Republic', 
 
    'TD' : 'Chad', 
 
    'CL' : 'Chile', 
 
    'CN' : 'China', 
 
    'CX' : 'Christmas Island', 
 
    'CC' : 'Cocos (Keeling) Islands', 
 
    'CO' : 'Colombia', 
 
    'KM' : 'Comoros', 
 
    'CG' : 'Congo', 
 
    'CD' : 'Congo, Democratic Republic', 
 
    'CK' : 'Cook Islands', 
 
    'CR' : 'Costa Rica', 
 
    'CI' : 'Cote D\'Ivoire', 
 
    'HR' : 'Croatia', 
 
    'CU' : 'Cuba', 
 
    'CY' : 'Cyprus', 
 
    'CZ' : 'Czech Republic', 
 
    'DK' : 'Denmark', 
 
    'DJ' : 'Djibouti', 
 
    'DM' : 'Dominica', 
 
    'DO' : 'Dominican Republic', 
 
    'EC' : 'Ecuador', 
 
    'EG' : 'Egypt', 
 
    'SV' : 'El Salvador', 
 
    'GQ' : 'Equatorial Guinea', 
 
    'ER' : 'Eritrea', 
 
    'EE' : 'Estonia', 
 
    'ET' : 'Ethiopia', 
 
    'FK' : 'Falkland Islands (Malvinas)', 
 
    'FO' : 'Faroe Islands', 
 
    'FJ' : 'Fiji', 
 
    'FI' : 'Finland', 
 
    'FR' : 'France', 
 
    'GF' : 'French Guiana', 
 
    'PF' : 'French Polynesia', 
 
    'TF' : 'French Southern Territories', 
 
    'GA' : 'Gabon', 
 
    'GM' : 'Gambia', 
 
    'GE' : 'Georgia', 
 
    'DE' : 'Germany', 
 
    'GH' : 'Ghana', 
 
    'GI' : 'Gibraltar', 
 
    'GR' : 'Greece', 
 
    'GL' : 'Greenland', 
 
    'GD' : 'Grenada', 
 
    'GP' : 'Guadeloupe', 
 
    'GU' : 'Guam', 
 
    'GT' : 'Guatemala', 
 
    'GG' : 'Guernsey', 
 
    'GN' : 'Guinea', 
 
    'GW' : 'Guinea-Bissau', 
 
    'GY' : 'Guyana', 
 
    'HT' : 'Haiti', 
 
    'HM' : 'Heard Island & Mcdonald Islands', 
 
    'VA' : 'Holy See (Vatican City State)', 
 
    'HN' : 'Honduras', 
 
    'HK' : 'Hong Kong', 
 
    'HU' : 'Hungary', 
 
    'IS' : 'Iceland', 
 
    'IN' : 'India', 
 
    'ID' : 'Indonesia', 
 
    'IR' : 'Iran, Islamic Republic Of', 
 
    'IQ' : 'Iraq', 
 
    'IE' : 'Ireland', 
 
    'IM' : 'Isle Of Man', 
 
    'IL' : 'Israel', 
 
    'IT' : 'Italy', 
 
    'JM' : 'Jamaica', 
 
    'JP' : 'Japan', 
 
    'JE' : 'Jersey', 
 
    'JO' : 'Jordan', 
 
    'KZ' : 'Kazakhstan', 
 
    'KE' : 'Kenya', 
 
    'KI' : 'Kiribati', 
 
    'KR' : 'Korea', 
 
    'KW' : 'Kuwait', 
 
    'KG' : 'Kyrgyzstan', 
 
    'LA' : 'Lao People\'s Democratic Republic', 
 
    'LV' : 'Latvia', 
 
    'LB' : 'Lebanon', 
 
    'LS' : 'Lesotho', 
 
    'LR' : 'Liberia', 
 
    'LY' : 'Libyan Arab Jamahiriya', 
 
    'LI' : 'Liechtenstein', 
 
    'LT' : 'Lithuania', 
 
    'LU' : 'Luxembourg', 
 
    'MO' : 'Macao', 
 
    'MK' : 'Macedonia', 
 
    'MG' : 'Madagascar', 
 
    'MW' : 'Malawi', 
 
    'MY' : 'Malaysia', 
 
    'MV' : 'Maldives', 
 
    'ML' : 'Mali', 
 
    'MT' : 'Malta', 
 
    'MH' : 'Marshall Islands', 
 
    'MQ' : 'Martinique', 
 
    'MR' : 'Mauritania', 
 
    'MU' : 'Mauritius', 
 
    'YT' : 'Mayotte', 
 
    'MX' : 'Mexico', 
 
    'FM' : 'Micronesia, Federated States Of', 
 
    'MD' : 'Moldova', 
 
    'MC' : 'Monaco', 
 
    'MN' : 'Mongolia', 
 
    'ME' : 'Montenegro', 
 
    'MS' : 'Montserrat', 
 
    'MA' : 'Morocco', 
 
    'MZ' : 'Mozambique', 
 
    'MM' : 'Myanmar', 
 
    'NA' : 'Namibia', 
 
    'NR' : 'Nauru', 
 
    'NP' : 'Nepal', 
 
    'NL' : 'Netherlands', 
 
    'AN' : 'Netherlands Antilles', 
 
    'NC' : 'New Caledonia', 
 
    'NZ' : 'New Zealand', 
 
    'NI' : 'Nicaragua', 
 
    'NE' : 'Niger', 
 
    'NG' : 'Nigeria', 
 
    'NU' : 'Niue', 
 
    'NF' : 'Norfolk Island', 
 
    'MP' : 'Northern Mariana Islands', 
 
    'NO' : 'Norway', 
 
    'OM' : 'Oman', 
 
    'PK' : 'Pakistan', 
 
    'PW' : 'Palau', 
 
    'PS' : 'Palestinian Territory, Occupied', 
 
    'PA' : 'Panama', 
 
    'PG' : 'Papua New Guinea', 
 
    'PY' : 'Paraguay', 
 
    'PE' : 'Peru', 
 
    'PH' : 'Philippines', 
 
    'PN' : 'Pitcairn', 
 
    'PL' : 'Poland', 
 
    'PT' : 'Portugal', 
 
    'PR' : 'Puerto Rico', 
 
    'QA' : 'Qatar', 
 
    'RE' : 'Reunion', 
 
    'RO' : 'Romania', 
 
    'RU' : 'Russian Federation', 
 
    'RW' : 'Rwanda', 
 
    'BL' : 'Saint Barthelemy', 
 
    'SH' : 'Saint Helena', 
 
    'KN' : 'Saint Kitts And Nevis', 
 
    'LC' : 'Saint Lucia', 
 
    'MF' : 'Saint Martin', 
 
    'PM' : 'Saint Pierre And Miquelon', 
 
    'VC' : 'Saint Vincent And Grenadines', 
 
    'WS' : 'Samoa', 
 
    'SM' : 'San Marino', 
 
    'ST' : 'Sao Tome And Principe', 
 
    'SA' : 'Saudi Arabia', 
 
    'SN' : 'Senegal', 
 
    'RS' : 'Serbia', 
 
    'SC' : 'Seychelles', 
 
    'SL' : 'Sierra Leone', 
 
    'SG' : 'Singapore', 
 
    'SK' : 'Slovakia', 
 
    'SI' : 'Slovenia', 
 
    'SB' : 'Solomon Islands', 
 
    'SO' : 'Somalia', 
 
    'ZA' : 'South Africa', 
 
    'GS' : 'South Georgia And Sandwich Isl.', 
 
    'ES' : 'Spain', 
 
    'LK' : 'Sri Lanka', 
 
    'SD' : 'Sudan', 
 
    'SR' : 'Suriname', 
 
    'SJ' : 'Svalbard And Jan Mayen', 
 
    'SZ' : 'Swaziland', 
 
    'SE' : 'Sweden', 
 
    'CH' : 'Switzerland', 
 
    'SY' : 'Syrian Arab Republic', 
 
    'TW' : 'Taiwan', 
 
    'TJ' : 'Tajikistan', 
 
    'TZ' : 'Tanzania', 
 
    'TH' : 'Thailand', 
 
    'TL' : 'Timor-Leste', 
 
    'TG' : 'Togo', 
 
    'TK' : 'Tokelau', 
 
    'TO' : 'Tonga', 
 
    'TT' : 'Trinidad And Tobago', 
 
    'TN' : 'Tunisia', 
 
    'TR' : 'Turkey', 
 
    'TM' : 'Turkmenistan', 
 
    'TC' : 'Turks And Caicos Islands', 
 
    'TV' : 'Tuvalu', 
 
    'UG' : 'Uganda', 
 
    'UA' : 'Ukraine', 
 
    'AE' : 'United Arab Emirates', 
 
    'GB' : 'United Kingdom', 
 
    'US' : 'United States', 
 
    'UM' : 'United States Outlying Islands', 
 
    'UY' : 'Uruguay', 
 
    'UZ' : 'Uzbekistan', 
 
    'VU' : 'Vanuatu', 
 
    'VE' : 'Venezuela', 
 
    'VN' : 'Viet Nam', 
 
    'VG' : 'Virgin Islands, British', 
 
    'VI' : 'Virgin Islands, U.S.', 
 
    'WF' : 'Wallis And Futuna', 
 
    'EH' : 'Western Sahara', 
 
    'YE' : 'Yemen', 
 
    'ZM' : 'Zambia', 
 
    'ZW' : 'Zimbabwe' 
 
}; 
 

 
console.log(getCountryFromHTTP("fr")); 
 
console.log(getCountryFromHTTP("pt-BR")); 
 
console.log(getCountryFromHTTP("pt-PT,pt;q=0.9,en;q=0.8,en-GB;q=0.7")); 
 
console.log(getCountryFromHTTP("pt;q=0.9,en;q=0.8,en-GB;q=0.7"));