如何使用 Selenium 2 发送 http RequestHeader?

发布于 2024-11-17 07:04:31 字数 2441 浏览 1 评论 0原文

我需要发送一个带有一些修改过的标头的 Http 请求。经过几个小时尝试找到与 Selenium 2 的 Selenium RC Selenium.addCustomRequestHeader 等效的方法后,我放弃了并使用 JavaScript 来实现我的目的。我预计这会容易得多!

有人知道更好的方法吗?

这就是我所做的:

javascript.js

var test = {
    "sendHttpHeaders": function(dst, header1Name, header1Val, header2Name, header2Val) {
        var http = new XMLHttpRequest();

        http.open("GET", dst, "false");
        http.setRequestHeader(header1Name,header1Val);
        http.setRequestHeader(header2Name,header2Val);
        http.send(null);
    }
}

MyTest.java

// ...

@Test
public void testFirstLogin() throws Exception {
    WebDriver driver = new FirefoxDriver();

    String url = System.getProperty(Constants.URL_PROPERTY_NAME);
    driver.get(url);

    // Using javascript to send http headers
    String scriptResource = this.getClass().getPackage().getName()
        .replace(".", "/") + "/javascript.js";

    String script = getFromResource(scriptResource)
            + "test.sendHttpHeaders(\"" + url + "\", \"" + h1Name
            + "\", \"" + h1Val + "\", \"" + h2Name + "\", \"" + h2Val + "\");";
    LOG.debug("script: " + script);

    ((JavascriptExecutor)driver).executeScript(loginScript);

    // ...
}

// I don't like mixing js with my code. I've written this utility method to get
// the js from the classpath
/**
 * @param src name of a resource that must be available from the classpath
 * @return new string with the contents of the resource
 * @throws IOException if resource not found
 */
public static String getFromResource(String src) throws IOException {
    InputStream is = Thread.currentThread().getContextClassLoader().
            getResourceAsStream(src);
    if (null == is) {
        throw new IOException("Resource " + src + " not found.");
    }
    InputStreamReader isr = new InputStreamReader(is);
    BufferedReader br = new BufferedReader(isr);
    StringWriter sw = new StringWriter();
    PrintWriter pw = new PrintWriter(sw);

    String line = null;
    int nLines = 0;
    while (null != (line = br.readLine())) {
        pw.println(line);
        nLines ++;
    }
    LOG.info("Resource " + src + " successfully copied into String (" + nLines + " lines copied).");
    return sw.toString();
}

// ...

注意:为了简化这篇文章,我编辑了我的原始代码。我希望我没有引入任何错误!

I needed to send an Http request with a few modified headers. After several hours trying to find an equivalent method to that of Selenium RC Selenium.addCustomRequestHeader for Selenium 2, I gave up and used JavaScript for my purposes. I have expected this to be a lot easier!

Does someone know a better method?

This is what I have done:

javascript.js

var test = {
    "sendHttpHeaders": function(dst, header1Name, header1Val, header2Name, header2Val) {
        var http = new XMLHttpRequest();

        http.open("GET", dst, "false");
        http.setRequestHeader(header1Name,header1Val);
        http.setRequestHeader(header2Name,header2Val);
        http.send(null);
    }
}

MyTest.java

// ...

@Test
public void testFirstLogin() throws Exception {
    WebDriver driver = new FirefoxDriver();

    String url = System.getProperty(Constants.URL_PROPERTY_NAME);
    driver.get(url);

    // Using javascript to send http headers
    String scriptResource = this.getClass().getPackage().getName()
        .replace(".", "/") + "/javascript.js";

    String script = getFromResource(scriptResource)
            + "test.sendHttpHeaders(\"" + url + "\", \"" + h1Name
            + "\", \"" + h1Val + "\", \"" + h2Name + "\", \"" + h2Val + "\");";
    LOG.debug("script: " + script);

    ((JavascriptExecutor)driver).executeScript(loginScript);

    // ...
}

// I don't like mixing js with my code. I've written this utility method to get
// the js from the classpath
/**
 * @param src name of a resource that must be available from the classpath
 * @return new string with the contents of the resource
 * @throws IOException if resource not found
 */
public static String getFromResource(String src) throws IOException {
    InputStream is = Thread.currentThread().getContextClassLoader().
            getResourceAsStream(src);
    if (null == is) {
        throw new IOException("Resource " + src + " not found.");
    }
    InputStreamReader isr = new InputStreamReader(is);
    BufferedReader br = new BufferedReader(isr);
    StringWriter sw = new StringWriter();
    PrintWriter pw = new PrintWriter(sw);

    String line = null;
    int nLines = 0;
    while (null != (line = br.readLine())) {
        pw.println(line);
        nLines ++;
    }
    LOG.info("Resource " + src + " successfully copied into String (" + nLines + " lines copied).");
    return sw.toString();
}

// ...

Notice: To simplify this post, I have edited my original code. I hope I haven't introduced any errors!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

动次打次papapa 2024-11-24 07:04:31

根据阿尔贝托的回答,如果您正在使用它,您可以将修改标头添加到 Firefox 配置文件中:

FirefoxDriver createFirefoxDriver() throws URISyntaxException, IOException {
    FirefoxProfile profile = new FirefoxProfile();
    URL url = this.getClass().getResource("/modify_headers-0.7.1.1-fx.xpi");
    File modifyHeaders = modifyHeaders = new File(url.toURI());

    profile.setEnableNativeEvents(false);
    profile.addExtension(modifyHeaders);

    profile.setPreference("modifyheaders.headers.count", 1);
    profile.setPreference("modifyheaders.headers.action0", "Add");
    profile.setPreference("modifyheaders.headers.name0", SOME_HEADER);
    profile.setPreference("modifyheaders.headers.value0", "true");
    profile.setPreference("modifyheaders.headers.enabled0", true);
    profile.setPreference("modifyheaders.config.active", true);
    profile.setPreference("modifyheaders.config.alwaysOn", true);

    DesiredCapabilities capabilities = new DesiredCapabilities();
    capabilities.setBrowserName("firefox");
    capabilities.setPlatform(org.openqa.selenium.Platform.ANY);
    capabilities.setCapability(FirefoxDriver.PROFILE, profile);
    return new FirefoxDriver(capabilities);
}

As per Alberto's answer you can add modify headers to the Firefox profile if you are using it:

FirefoxDriver createFirefoxDriver() throws URISyntaxException, IOException {
    FirefoxProfile profile = new FirefoxProfile();
    URL url = this.getClass().getResource("/modify_headers-0.7.1.1-fx.xpi");
    File modifyHeaders = modifyHeaders = new File(url.toURI());

    profile.setEnableNativeEvents(false);
    profile.addExtension(modifyHeaders);

    profile.setPreference("modifyheaders.headers.count", 1);
    profile.setPreference("modifyheaders.headers.action0", "Add");
    profile.setPreference("modifyheaders.headers.name0", SOME_HEADER);
    profile.setPreference("modifyheaders.headers.value0", "true");
    profile.setPreference("modifyheaders.headers.enabled0", true);
    profile.setPreference("modifyheaders.config.active", true);
    profile.setPreference("modifyheaders.config.alwaysOn", true);

    DesiredCapabilities capabilities = new DesiredCapabilities();
    capabilities.setBrowserName("firefox");
    capabilities.setPlatform(org.openqa.selenium.Platform.ANY);
    capabilities.setCapability(FirefoxDriver.PROFILE, profile);
    return new FirefoxDriver(capabilities);
}
一口甜 2024-11-24 07:04:31

不幸的是,您无法使用 Selenium 2 更改标头。这是团队的一个有意识的决定,因为我们正在尝试创建一个浏览器自动化框架来模拟用户可以执行的操作。

Unfortunately you can not change headers with Selenium 2. This has been a conscious decision on the teams part as we are trying to create a browser automation framework that emulates what a user can do.

春庭雪 2024-11-24 07:04:31

两周前我遇到了同样的问题。我尝试了卡尔建议的方法,但实现这项任务似乎有点“开销”。

最后,我使用了 fiddlerCore 库来在我的代码中托管代理服务器,并且只使用 Web 驱动程序 2 的内置代理功能。在我看来,它工作得很好,并且更加直观/稳定。此外,它适用于所有浏览器,并且您不依赖于需要在代码存储库中维护的二进制文件。

这是一个用 C# 为 Chrome 制作的示例(Firefox 和 IE 非常相似)

// Check if the server is already running
if (!FiddlerApplication.IsStarted())
{
    // Append your delegate to the BeforeRequest event
    FiddlerApplication.BeforeRequest += delegate(Fiddler.Session oS)
    {
        // Make the modifications needed - change header, logging, ...
        oS.oRequest["SM_USER"] = SeleniumSettings.TestUser;
    };
    // Startup the proxy server
    FiddlerApplication.Startup(SeleniumSettings.ProxyPort, false, false);
}

// Create the proxy setting for the browser
var proxy = new Proxy();
proxy.HttpProxy = string.Format("localhost:{0}", SeleniumSettings.ProxyPort);

// Create ChromeOptions object and add the setting
var chromeOptions = new ChromeOptions();
chromeOptions.Proxy = proxy;

// Create the driver
var Driver = new ChromeDriver(path, chromeOptions);

// Afterwards shutdown the proxy server if it's running
if (FiddlerApplication.IsStarted())
{
    FiddlerApplication.Shutdown();
}

I encountered the same issue 2 weeks ago. I tried the approach suggested by Carl but it seemed a bit to much "overhead" to realize this task.

In the end I used the fiddlerCore library in order to host a proxy server in my code and just use the build in proxy feature of web driver 2. It works pretty good and is much more intuitive/stable in my opinion. Furthermore it works for all browsers and you don't depend on binary files which you need to maintain inside your code repository.

Here an example made in C# for Chrome (Firefox and IE are very similar)

// Check if the server is already running
if (!FiddlerApplication.IsStarted())
{
    // Append your delegate to the BeforeRequest event
    FiddlerApplication.BeforeRequest += delegate(Fiddler.Session oS)
    {
        // Make the modifications needed - change header, logging, ...
        oS.oRequest["SM_USER"] = SeleniumSettings.TestUser;
    };
    // Startup the proxy server
    FiddlerApplication.Startup(SeleniumSettings.ProxyPort, false, false);
}

// Create the proxy setting for the browser
var proxy = new Proxy();
proxy.HttpProxy = string.Format("localhost:{0}", SeleniumSettings.ProxyPort);

// Create ChromeOptions object and add the setting
var chromeOptions = new ChromeOptions();
chromeOptions.Proxy = proxy;

// Create the driver
var Driver = new ChromeDriver(path, chromeOptions);

// Afterwards shutdown the proxy server if it's running
if (FiddlerApplication.IsStarted())
{
    FiddlerApplication.Shutdown();
}
盗梦空间 2024-11-24 07:04:31

(这个例子是使用 Chrome 完成的)

这就是我解决我的问题的方法。希望对具有类似设置的任何人都有帮助。

  1. 将ModHeader扩展添加到chrome浏览器

如何下载Modheader?链接

ChromeOptions options = new ChromeOptions();
options.addExtensions(new File(C://Downloads//modheader//modheader.crx));

// Set the Desired capabilities 
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setCapability(ChromeOptions.CAPABILITY, options);

// Instantiate the chrome driver with capabilities
WebDriver driver = new RemoteWebDriver(new URL(YOUR_HUB_URL), options);
  1. 转到浏览器扩展并捕获 ModHeader 的本地存储上下文 ID

Capture ID from ModHeader

  1. 导航到 ModHeader 的 URL 以设置本地存储上下文

// set the context on the extension so the localStorage can be accessed
driver.get("chrome-extension://idgpnmonknjnojddfkpgkljpfnnfcklj/_generated_background_page.html");

Where `idgpnmonknjnojddfkpgkljpfnnfcklj` is the value captured from the Step# 2
  1. 现在使用 Javascript 将标头添加到请求中

   ((Javascript)driver).executeScript(
         "localStorage.setItem('profiles', JSON.stringify([{  title: 'Selenium', hideComment: true, appendMode: '', 
             headers: [                        
               {enabled: true, name: 'token-1', value: 'value-1', comment: ''},
               {enabled: true, name: 'token-2', value: 'value-2', comment: ''}
             ],                          
             respHeaders: [],
             filters: []
          }]));");

其中 token-1value-1token-2value-2 是请求标头和值有待补充。

  1. 现在导航到所需的 Web 应用程序。

    driver.get("您想要的网站");

(This example is done using Chrome)

This is how I fixed the problem in my case. Hopefully, might be helpful for anyone with a similar setup.

  1. Add the ModHeader extension to the chrome browser

How to download the Modheader? Link

ChromeOptions options = new ChromeOptions();
options.addExtensions(new File(C://Downloads//modheader//modheader.crx));

// Set the Desired capabilities 
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setCapability(ChromeOptions.CAPABILITY, options);

// Instantiate the chrome driver with capabilities
WebDriver driver = new RemoteWebDriver(new URL(YOUR_HUB_URL), options);
  1. Go to the browser extensions and capture the Local Storage context ID of the ModHeader

Capture ID from ModHeader

  1. Navigate to the URL of the ModHeader to set the Local Storage Context

.

// set the context on the extension so the localStorage can be accessed
driver.get("chrome-extension://idgpnmonknjnojddfkpgkljpfnnfcklj/_generated_background_page.html");

Where `idgpnmonknjnojddfkpgkljpfnnfcklj` is the value captured from the Step# 2
  1. Now add the headers to the request using Javascript

.

   ((Javascript)driver).executeScript(
         "localStorage.setItem('profiles', JSON.stringify([{  title: 'Selenium', hideComment: true, appendMode: '', 
             headers: [                        
               {enabled: true, name: 'token-1', value: 'value-1', comment: ''},
               {enabled: true, name: 'token-2', value: 'value-2', comment: ''}
             ],                          
             respHeaders: [],
             filters: []
          }]));");

Where token-1, value-1, token-2, value-2 are the request headers and values that are to be added.

  1. Now navigate to the required web-application.

    driver.get("your-desired-website");

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文