Мне нужно определить страну пользователей, но я пытаюсь избежать всего вызова внешней службы, чтобы получить местоположение на основе IP или внутренней базы данных. Мне нужно сделать эту услугу очень отзывчивой, и для запроса любой внешней службы требуется почти полсекунды, поэтому я пытаюсь избежать этого. Также любой вызов db будет дорогостоящим для этого подхода. Мне нужна страница для ответа менее чем за 20 мс.
Мой вопрос. Кто-нибудь знает, насколько это возможно? Я знаю, что страна не всегда присутствует, или пользователи могут менять язык по умолчанию или присутствовать в другой стране со своими компьютерами.
Кто-нибудь имел предыдущий опыт или есть какая-либо документация (я не мог найти один googling или на странице w3), который указывает процент точности или ошибки с использованием этого подхода?
Ответ 3
Пользователь @TheHippo абсолютно прав. Использование Accept-Language
HTTP-информации действительно ненадежно, чтобы получить пользовательскую страну. Хотя он имеет мало преимуществ, таких как скорость, поскольку он не зависит от внешних служб для отслеживания страны от IP. Вы можете попробовать использовать его в качестве бэкэнд-сервиса, когда недоступны службы типа geoIP или когда вы предоставляете вам страну, в которой ваш сайт не отображается или пользователи не обслуживают.
Я использую эту функцию как вспомогательную услугу, когда результат от служб типа geoIP не удовлетворяет. Для этого также проверьте документацию.
//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\ 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"));