WebView - 在每个请求上定义用户代理

时间:2016-03-07 23:35:11

标签: c# webview httprequest win-universal-app windows-10-universal

目前,我正在设置请求消息的User-Agent,如下所示:

var rm = new HttpRequestMessage(HttpMethod.Post, new Uri("http://example.com"));       
rm.Headers.Add("User-Agent", "UserAgentString");
webView.NavigateWithHttpRequestMessage(rm);

一切都按预期工作。

但是,当我导航到另一个页面时,例如,通过点击网站上的链接,用户代理将重置为默认的WebView

有没有办法设置用户代理永久或在每次请求时更改?

谢谢, 乔治

3 个答案:

答案 0 :(得分:2)

The only way I've been able to get this to work fairly reliably is by using the NavigationStarting Event to cancel the page load and get the current url, then use a custom event to trigger the new page load with the correct UA.

public sealed partial class MainPage : Page
{
    private bool headerSent;
    private Uri uri;

    private delegate void NavigateHandler(object sender, EventArgs e);
    private event NavigateHandler OnNavigate;

    public MainPage()
    {
        this.InitializeComponent();

        this.OnNavigate += new NavigateHandler(Navigate);
        this.headerSent = false;
        this.webview.Navigate(new Uri("https://netflix.com"));
    }

    private void Navigate(object sender, EventArgs e)
    {
        this.headerSent = true;
        var rm = new HttpRequestMessage(HttpMethod.Post, this.uri);

        rm.Headers.Add("User-Agent", @"Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 Edge/12.10136");
        this.webview.NavigateWithHttpRequestMessage(rm);
    }

    private void webview_NavigationStarting(WebView sender, WebViewNavigationStartingEventArgs args)
    {
        if (!headerSent)
        {
            args.Cancel = true;
            this.uri = args.Uri;
            OnNavigate(this, new EventArgs());
        }
        else if (headerSent)
        {
            headerSent = false;
        }
    }
}

Not pretty, but it seems to work.

答案 1 :(得分:1)

NavigationStarting在webview导航到新内容之前发生。您可以取消该操作获取args.Uri并使用HttpRequestMessage导航。还有FrameNavigationStarting

WebView wb = new WebView();
wb.NavigationStarting += A_NavigationStarting;

private void A_NavigationStarting(WebView sender, WebViewNavigationStartingEventArgs args)
{
    //this will throw `StackOverflowException` so you have to add a condition here
    if(handled)
    {
        args.Cancel = true;
        var rm = new HttpRequestMessage(HttpMethod.Post, args.Uri);

        rm.Headers.Add("User-Agent", "UserAgentString");
        sender.NavigateWithHttpRequestMessage(rm);
    }
}

答案 2 :(得分:0)

我找到了this trick by Matt Dot。这将永久更改用户代理字符串。任何WebView请求(无论是手动还是通过HTML内部的链接点击)都会将您的值作为User-Agent标头发送。

这是链接死亡时的来源。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace UA
{
    public static class UserAgent
    {
        const int URLMON_OPTION_USERAGENT = 0x10000001;

        [DllImport("urlmon.dll", CharSet = CharSet.Ansi)]
        private static extern int UrlMkSetSessionOption(int dwOption, string pBuffer, int dwBufferLength, int dwReserved);

        [DllImport("urlmon.dll", CharSet = CharSet.Ansi)]
        private static extern int UrlMkGetSessionOption(int dwOption, StringBuilder pBuffer, int dwBufferLength, ref int pdwBufferLength, int dwReserved);

        public static string GetUserAgent()
        {
            int capacity = 255;
            var buf = new StringBuilder(capacity);
            int length = 0;

            UrlMkGetSessionOption(URLMON_OPTION_USERAGENT, buf, capacity, ref length, 0);

            return buf.ToString();
        }

        public static void SetUserAgent(string agent)
        {
            var hr = UrlMkSetSessionOption(URLMON_OPTION_USERAGENT, agent, agent.Length, 0);
            var ex = Marshal.GetExceptionForHR(hr);
            if(null != ex)
            {
                throw ex;
            }
        }

        public static void AppendUserAgent(string suffix)
        {
            SetUserAgent(GetUserAgent() + suffix);
        }
    }
}

您可以在应用中的任何位置更改此值,但如果您希望永久设置,请使用App.xaml.cs构造函数:

public App()
{
    UA.UserAgent.SetUserAgent("Firefox ;)");

    // ...
}