Почему файлы cookie не распознаются при нажатии ссылки из внешнего источника (например, Excel, Word и т.д.)
Я заметил, что когда ссылка вызывается извне из веб-браузера, например из Excel или Word, что мой сеансовый файл изначально непризнан, даже если ссылка открывается на новой вкладке того же окна браузера.
В конечном итоге браузер узнает о своем cookie, но я озадачен тем, почему эта начальная ссылка из Excel или Word не работает. Чтобы сделать его еще более сложным, щелчок по ссылке отлично работает в Outlook.
Кто-нибудь знает, почему это может произойти? Я использую Zend Framework с PHP 5.3.
Ответы
Ответ 1
Это связано с тем, что MS Office использует компонент Hlink.dll для поиска, если ссылка является документом Office или чем-то еще. MS Office планирует открыть документ, связанный внутри документов, без помощи внешнего браузера (используя компонент Hlink.dll IE6).
Если cookie cookie защищает веб-сайт, Hlink, естественно, перенаправляется на страницу входа в систему, и, достигнув HTML-страницы и неспособной "понять", она открывается во внешнем браузере. Обратите внимание, что он открывает не оригинальный URL (ожидаемое поведение), а результат перенаправления, даже если он был перенаправлен на 302.
У Microsoft есть эта ошибка в неподдерживаемом компоненте (Hlink.dll), вместо того, чтобы распознать ошибку, перевернуть ее на голову (пытается убедите нас, что это недостаток системы SSO, которую мы используем, т.е. файлы cookie сеансов) и отказывается ее обновлять. Он предлагает обходной путь, который отключает функциональность поиска в MS Office:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\
Office\9.0\Common\Internet\ForceShellExecute:DWORD=1
Или предложите нам обходные серверы, чтобы избежать перенаправления HTTP и изменения в переадресации Javascript или перенаправлений META REFRESH (т.е. чтобы Hlink получить текст/html-страницу по исходному URL-адресу и заставить запустить внешний браузер для ее обработки).
Ответ 2
У нас была такая же проблема, и мы писали камень с открытым исходным кодом, чтобы помочь тем, кто использует рельсы: https://github.com/spilliton/fix_microsoft_links
Вы можете использовать тот же подход, который мы использовали в любой среде:
- Обнаружение, если пользовательский агент из продукта Microsoft
- Извлеките пустую страницу html с тегом meta refresh, который заставит браузер обновить страницу с помощью правильных файлов cookie.
Пример кода здесь: https://github.com/spilliton/fix_microsoft_links/blob/master/lib/fix_microsoft_links.rb
Ответ 3
На стороне сервера это работало для меня в IIS (с использованием правила перезаписи)
<rule name="WordBypass" enabled="true" stopProcessing="true">
<match url=".*" />
<conditions>
<add input="{HTTP_USER_AGENT}" pattern="Word|Excel|PowerPoint|ms-office" />
</conditions>
<action type="CustomResponse" statusCode="200" statusReason="Refresh" statusDescription="Refresh" />
</rule>
Ответ 4
Вот решение для С# ASP.NET, основанного на ответе spilliton выше. В Global.asax.cs добавьте следующее:
private static string MSUserAgentsRegex = @"[^\w](Word|Excel|PowerPoint|ms-office)([^\w]|\z)";
protected void Application_OnPostAuthenticateRequest(object sender, EventArgs e)
{
if (System.Text.RegularExpressions.Regex.IsMatch(Request.UserAgent, MSUserAgentsRegex))
{
Response.Write("<html><head><meta http-equiv='refresh' content='0'/></head><body></body></html>");
Response.End();
}
}
Ответ 5
Исправлено для VB.NET:
Dim userAgent As String = System.Web.HttpContext.Current.Request.UserAgent
If userAgent.Contains("Word") Or userAgent.Contains("Excel") Or userAgent.Contains("PowerPoint") Or userAgent.Contains("ms-office") Then
System.Web.HttpContext.Current.Response.Clear()
System.Web.HttpContext.Current.Response.Write("<html><head><meta http-equiv='refresh' content='0'/></head><body></body></html>")
System.Web.HttpContext.Current.Response.End()
End If
В основном это заставляет браузер обновлять страницу, поэтому запрос приходит с помощью агента пользователя браузера и всех правильных файлов cookie.
Ответ 6
Решение PHP:
Это предотвращает распознавание перенаправления MS-продуктом. Поэтому MS запускает браузер из необходимой ссылки.
if (isset($_SERVER['HTTP_USER_AGENT']))
{
$http_user_agent = $_SERVER['HTTP_USER_AGENT'];
if (preg_match('/Word|Excel|PowerPoint|ms-office/i', $http_user_agent))
{
// Prevent MS office products detecting the upcoming re-direct .. forces them to launch the browser to this link
die();
}
}
.. перенаправить после этого кода
Ответ 7
1. Из выражения excel/word в http://example.com/from_excel.php
2.In "from_excel.php" перенаправлять на страницу, где вы используете сеанс
<script>document.location.href = "http://example.com/page_with_session.php"; </script>
Ответ 8
Мы видим проблему в том, что при щелчке URL-адреса в MS Word открывается две вкладки Chrome, а на открываемой странице перенаправляется JavaScript: window.location.href=blabla
Отладкой со стороны серверов мы подтвердили, что помимо приложения Chrome отправляются запросы из приложения Office. Это так странно.
Но в любом случае, проверив заголовок запроса "Пользователь-агент" и вернув пустую страницу в приложения Office, наша проблема с двумя вкладками была решена. Это определенно правильно!
Ответ 9
Вот мое решение для этого в WordPress. Добавьте это в functions.php в свою тему или в другой файл плагина.
Это может быть полезно, если ваша система, например WP, отправляет зарегистрированных пользователей на страницу входа с перенаправлением на страницу, к которой они пытались получить доступ. Word отправлял пользователей на эту страницу, но тогда WP не правильно обрабатывал случай, когда пользователь уже вошел в систему. Этот код проверяет, есть ли текущий пользователь и передан параметр redirect_to. Если это так, он перенаправляется в местоположение redirect_to.
function my_logged_in_redirect_to()
{
global $current_user;
if($current_user->ID && $_REQUEST['redirect_to'])
{
wp_redirect($_REQUEST['redirect_to']);
exit;
}
}
add_action('wp', 'my_logged_in_redirect_to');
Ответ 10
Здесь исправление VBA для Excel. Та же концепция может быть применена для Microsoft Word. В принципе, вместо того, чтобы отключить ссылку из Excel, код выполняет ссылку изнутри оболочки.
Здесь код:
Private Sub Worksheet_FollowHyperlink(ByVal objLink As Hyperlink)
Application.EnableEvents = False
Dim strAddress As String
strAddress = "explorer " & objLink.TextToDisplay
Dim dblReturn As Double
dblReturn = Shell(strAddress)
Application.EnableEvents = True
End Sub
- Для листа Excel, содержащего ссылки, щелкните правой кнопкой мыши вкладку листа и нажмите Просмотреть код. Появится редактор VBA.
- Вставьте код в окно и закройте редактор.
- Измените каждую ссылку на странице, чтобы она просто указывала на ячейку, в которой она находится. Для этого:
- Щелкните правой кнопкой мыши ссылку и нажмите Изменить гиперссылку. Появится окно "Редактировать гиперссылку".
- Нажмите Место в этом документе.
- Нажмите имя листа.
- Для Введите ссылку на ячейку, введите ссылку на ячейку (например, A4).
- Нажмите ОК.
Несколько примечаний:
- Вам нужно будет сохранить таблицу в виде таблицы с поддержкой макросов
(.xlsm). Когда пользователи открывают электронную таблицу, им будет предложено
включить макросы. Если они ответят "Нет", ссылки не будут работать.
- Эти инструкции основаны на Excel 2010. Предположительно, более поздние версии схожи.
Ответ 11
Я не могу поверить, что они называют это функцией. Однако, вот исправление для Apache:
RewriteEngine On
# Send a 200 to MS Office so it just hands over control to the browser
# It does not use existing session cookies and would be redirected to the login page otherwise
# https://www.wimpyprogrammer.com/microsoft-office-link-pre-fetching-and-single-sign-on/
RewriteCond %{HTTP_USER_AGENT} ;\sms-office(\)|;)
RewriteRule .* - [R=200,L]
Не может быть наилучшей производительности, так как вся страница отправляется вместо пустого ответа, но я не хотел добавлять другие модули Apache только для исправления такой идиотической функции ^ H ^ H ^ H ^ H.
Ответ 12
Вот пример исправления с использованием промежуточного программного обеспечения ядра dotnet:
public class MicrosoftOfficeLinksHandlingMiddleware
{
private static readonly Regex MsUserAgentsRegex = new Regex(@"[^\w](Word|Excel|PowerPoint|ms-office)([^\w]|\z)");
private readonly RequestDelegate _next;
public MicrosoftOfficeLinksHandlingMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext context)
{
string userAgent = context.Request.Headers["User-Agent"].FirstOrDefault();
if (userAgent != null && MsUserAgentsRegex.IsMatch(userAgent))
{
// just return an empty response to the office agent
return;
}
await _next(context);
}
}
Ответ 13
Мне пришлось решить эту проблему для сайта ASP.NET, но я только хотел использовать javascript/jQuery:
var isCoBrowse = ('<%= Session["user"].ToString().ToLower() %>' != '0');
if (isCoBrowse && window.location.href.indexOf('ReturnUrl=') >= 0 && window.location.href.indexOf('dllCheq') == -1) {
//redirect to the ReturnUrl & add dllCheq to the URI
var toRedirect = decodeURIComponent(gup('ReturnUrl', window.location.href)) + '&dllCheq';
window.location = toRedirect;
}
Я получил функцию gup:
Как получить значение из параметра URL?
Ответ 14
Используйте исправление, предоставленное ссылкой на Microsoft® ниже. https://support.microsoft.com/en-us/kb/218153
Ответ 15
Вот как обойти это с Java и Spring через фильтр:
/**
* To see why this is necessary, check out this page:
* https://support.microsoft.com/en-gb/help/899927.
*/
public class MicrosoftFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(final HttpServletRequest request,
final HttpServletResponse response,
final FilterChain filterChain) throws ServletException, IOException {
//Serve up a blank page to anything with a Microsoft Office user agent, forcing it to open the
//URL in a browser instead of trying to pre-fetch it, getting redirected to SSO, and losing
//the path of the original link.
if (!request.getHeader("User-Agent").contains("ms-office")) {
filterChain.doFilter(request, response);
}
}
}
/**
* Security configuration.
*/
@Configuration
public class SecurityConfiguration {
@Bean
public FilterRegistrationBean microsoftFilterRegistrationBean() {
FilterRegistrationBean<MicrosoftFilter> registrationBean = new FilterRegistrationBean<>();
registrationBean.setFilter(new MicrosoftFilter());
registrationBean.setOrder(Ordered.HIGHEST_PRECEDENCE);
return registrationBean;
}
}
Ответ 16
Я нашел исправление для Office 2013 и более поздних версий. Вы можете установить следующее исправление: https://support.microsoft.com/en-us/help/218153/error-message-when-clicking-hyperlink-in-office-cannot-locate-the-inte
Это решение сработало для меня.
Ответ 17
Компьютеры никогда suck.they не делают, как они supost к do.they хороши только для просмотра порно играть в игры, которые будут гнить мозг Но все же мы все еще трахаться с пока мы не сойти с ума
Ответ 18
Решение NGINX ниже:
if ($http_user_agent ~* Word|Excel|PowerPoint|ms-office) {
return 200 '<html><head><meta http-equiv="refresh" content="0"/></head><body></body></html>';
}
Вы можете поместить его в блок server
или location
.
Работает как шарм.
Ответ 19
Я подозреваю, что это вопрос того, как вы настраиваете файлы cookie.
Из-за характера создания веб-сайта example.com не рассматривается как тот же домен, что и www.example.com
; следовательно: вы можете войти в систему www.example.com
и не войти в систему example.com
.
Иными словами, проверьте URL в своем слове или файле excel - это тот же домен, что и вы вошли в свой браузер?
Есть два исправления/решения этой непоследовательности cookie:
1. перенаправлять всех, кто пытается загрузить ваш сайт без www. на ту же страницу с www. (или наоборот), или
2. Когда вы устанавливаете файл cookie, не забудьте указать аргумент домена как ".example.com". Ведущая точка указывает, что файл cookie должен быть действительным и для всех поддоменов этого домена.
Я подозреваю причину, по которой браузер, в конце концов, признает, что это потому, что вы, вероятно, в конечном итоге попадаете на URL с той же структурой домена, что и вы вошли в систему.
Надеюсь, что это поможет.