我有没有办法捕获从我的应用发送的所有HTTP请求,并在发送之前修改其标头?我想修改他们的referer
标题,以便发送请求的服务器认为它们来自Web浏览器而不是移动应用程序。谢谢!
更新:为了向您提供更多上下文,我计划使用Phonegap将Chrome扩展程序Instant Music移植到Android应用中。一些允许在PC上播放的YouTube视频不允许在手机上播放,我怀疑是因为嵌入Android应用内的youtube播放器没有推荐人标题。我正在尝试找到解决此问题的方法,以便我也可以在移动设备上播放此类视频。
答案 0 :(得分:8)
Youtube会检测用户浏览器Agent String
,其中包含有关浏览器的信息。如果您使用WebView
来显示YouTube视频,则可以设置WebView
' s Agent String
。
您可以在Internet上找到不同浏览器的代理字符串。我在这里找到了一些:Agent Strings。
以下是我如何通过模仿Firefox浏览器播放手机上不允许的Bob Marley的歌曲:
package com.my.myapplication;
import android.app.Activity;
import android.os.Bundle;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Toast;
public class MyActivity extends Activity {
private WebView mWebView ;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mWebView = new WebView(this);
// Enable javascript
mWebView.getSettings().setJavaScriptEnabled(true);
// Impersonate Mozzila browser
mWebView.getSettings().setUserAgentString("Mozilla/5.0 (Windows NT 6.2; Win64; x64; rv:21.0.0) Gecko/20121011 Firefox/21.0.0");
final Activity activity = this;
mWebView.setWebViewClient(new WebViewClient() {
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
Toast.makeText(activity, description, Toast.LENGTH_SHORT).show();
}
});
mWebView .loadUrl("http://youtube.com/watch?v=x59kS2AOrGM");
setContentView(mWebView);
}
}
编辑:
您还需要授予您的活动使用互联网的权限,方法是将此行添加到AndroidManifest.xml
:
<uses-permission android:name="android.permission.INTERNET" />
答案 1 :(得分:5)
您可以像这样轻松设置标题:
final String USER_AGENT = "Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2049.0 Safari/537.36";
final String URL = "http://www.cnn.com";
final String REFERER_URL = "http://www.w3.org/hypertext/DataSources/Overview.html";
HttpClient httpclient = new DefaultHttpClient();
HttpGet request = new HttpGet(URL);
// add request header
request.addHeader("User-Agent", USER_AGENT);
request.addHeader("Referer", REFERER_URL);
try {
HttpResponse response = httpclient.execute(request);
} catch (Exception e) {
// ...
}
我也添加了“User-Agent”,因为大多数网站都使用“User-Agent”而不是“Referer”来确定客户端是否是移动浏览器。
请注意,“Referer”拼写错误;这是我的代码中的故意。见this link。多年前猜测这是一个错字,只是卡住了。
答案 2 :(得分:5)
免责声明:肮脏的黑客,仅在Android 4.4上测试过,但应该适用于Android 4.0及更高版本。
需要尽早调用setupURLStreamHandlerFactory()方法,并使用URL.setURLStreamHandlerFactory()
设置我们自己的URL流处理程序工厂。工厂用于通过URL.openConnection()
打开的所有连接。我们为所有http:// ...网址设置了一个特殊的处理程序,用于设置&#39; Referer&#39;创建的HttpUrlConnection上的标题。
private static String REFERER_URL = "http://www.example.com/referer";
private void setupURLStreamHandlerFactory() {
URL.setURLStreamHandlerFactory(new URLStreamHandlerFactory() {
@Override
public URLStreamHandler createURLStreamHandler(String protocol) {
if ("http".equals(protocol)) {
try {
String className = Build.VERSION.SDK_INT < 19 ? "libcore.net.http.HttpHandler" : "com.android.okhttp.HttpHandler";
URLStreamHandler streamHandler = (URLStreamHandler) Class
.forName(className).newInstance();
return wrap(streamHandler);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
return null;
}
});
}
private static URLStreamHandler wrap(final URLStreamHandler streamHandler) {
return new URLStreamHandler() {
@Override
protected URLConnection openConnection(URL u) throws IOException {
URLConnection conn;
try {
Method openConnectionMethod = URLStreamHandler.class
.getDeclaredMethod("openConnection", URL.class);
openConnectionMethod.setAccessible(true);
conn = (URLConnection) openConnectionMethod.invoke(
streamHandler, u);
conn.setRequestProperty("Referer", REFERER_URL);
return conn;
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
} catch (IllegalArgumentException e) {
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
if (e.getTargetException() instanceof IOException) {
throw (IOException) e.getTargetException();
} else {
throw new RuntimeException(e);
}
}
}
};
}
编辑:已修改为适用于Android 4.4 Kitkat之前的版本