Проблема с Android файлом Android WebView
У меня есть сервер, который отправляет мое приложение для Android файл cookie сеанса, который будет использоваться для
аутентифицированное сообщение. Я пытаюсь загрузить WebView с URL-адресом
указывая на тот же сервер, и я пытаюсь пройти в сеансе
cookie для аутентификации. Я наблюдаю, что он работает
с перерывами, но я понятия не имею, почему. Я использую тот же самый cookie сеанса, чтобы делать другие вызовы на моем сервере, и они никогда не завершают проверку подлинности. Я наблюдаю эту проблему только при попытке загрузить URL-адрес в WebView, и это происходит не каждый раз. Очень расстраивает.
Ниже приведен код, который я использую для этого. Любая помощь будет оценена.
String myUrl = ""http://mydomain.com/";
CookieSyncManager.createInstance(this);
CookieManager cookieManager = CookieManager.getInstance();
Cookie sessionCookie = getCookie();
if(sessionCookie != null){
String cookieString = sessionCookie.getName() +"="+sessionCookie.getValue()+"; domain="+sessionCookie.getDomain();
cookieManager.setCookie(myUrl, cookieString);
CookieSyncManager.getInstance().sync();
}
WebView webView = (WebView) findViewById(R.id.webview);
webView.getSettings().setBuiltInZoomControls(true);
webView.getSettings().setJavaScriptEnabled(true);
webView.setWebViewClient(new MyWebViewClient());
webView.loadUrl(myUrl);
Ответы
Ответ 1
Спасибо justingrammens! Это сработало для меня, мне удалось поделиться файлом cookie в моих запросах DefaultHttpClient и деятельности WebView:
//------- Native request activity
private DefaultHttpClient httpClient;
public static Cookie cookie = null;
//After Login
List<Cookie> cookies = httpClient.getCookieStore().getCookies();
for (int i = 0; i < cookies.size(); i++) {
cookie = cookies.get(i);
}
//------- Web Browser activity
Cookie sessionCookie = myapp.cookie;
CookieSyncManager.createInstance(this);
CookieManager cookieManager = CookieManager.getInstance();
if (sessionCookie != null) {
cookieManager.removeSessionCookie();
String cookieString = sessionCookie.getName() + "=" + sessionCookie.getValue() + "; domain=" + sessionCookie.getDomain();
cookieManager.setCookie(myapp.domain, cookieString);
CookieSyncManager.getInstance().sync();
}
Ответ 2
Решение: Webview CookieSyncManager
CookieSyncManager cookieSyncManager = CookieSyncManager.createInstance(mWebView.getContext());
CookieManager cookieManager = CookieManager.getInstance();
cookieManager.setAcceptCookie(true);
cookieManager.removeSessionCookie();
cookieManager.setCookie("http://xx.example.com","mid="+MySession.GetSession().sessionId+" ; Domain=.example.com");
cookieSyncManager.sync();
String cookie = cookieManager.getCookie("http://xx.example.com");
Log.d(LOGTAG, "cookie ------>"+cookie);
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.setWebViewClient(new TuWebViewClient());
mWebView.loadUrl("http://xx.example.com");
Ответ 3
решение должно дать Android достаточно времени для файлов cookie. Вы можете найти более подробную информацию здесь: http://code.walletapp.net/post/46414301269/passing-cookie-to-webview
Ответ 4
Спасибо Android за то, что я разрушил свое воскресенье., Вот что фиксировало мои приложения (после того, как вы начали веб-просмотр)
if ( Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ) {
CookieManager cookieManager = CookieManager.getInstance();
cookieManager.setAcceptThirdPartyCookies( webView, true );
}
Я бы сказал, что вышеупомянутые ответы, вероятно, сработают, но в моей ситуации момент Android пошел v5 + мой андроид webview javascript 'apps' умер.
Ответ 5
Я потратил большую половину 3 часов на очень похожую проблему. В моем случае у меня было несколько вызовов, которые я сделал в веб-службе с помощью DefaulHttpClient
, а затем я хотел установить сеанс и все другие соответствующие файлы cookie в своем WebView
.
Я не знаю, поможет ли это решить вашу проблему, так как я не знаю, что делает ваш метод getCookie()
, но в моем случае мне действительно нужно было позвонить.
cookieManager.removeSessionCookie();
Сначала удалите файл cookie сеанса, а затем повторно добавьте его. Я обнаружил, что, когда я пытался установить cookie JSESSIONID
, не удалив его сначала, значение, которое я хотел установить, не сохранялось. Не уверен, что это поможет вам в конкретной проблеме, но подумал, что я поделюсь тем, что нашел.
Ответ 6
Я бы сохранил этот cookie сеанса в качестве предпочтения и решительно переустановил его менеджер файлов cookie. Похоже, что cookie сеанса не выдержал перезапуск Activity
Ответ 7
У меня есть другой подход от других людей здесь, и это подход, который гарантированно работает без обращения к CookieSyncManager (где вы находитесь во власти семантики вроде "Обратите внимание, что даже sync() происходит асинхронно" ).
По сути, мы переходим к правильному домену, затем мы запускаем javascript из контекста страницы для установки файлов cookie для этого домена (так же, как и сама страница). Два недостатка метода заключаются в том, что они могут ввести дополнительное время в оба конца из-за дополнительной просьбы о том, что вам нужно сделать; и если ваш сайт не имеет эквивалента пустой страницы, он может мигать любым URL-адресом, который вы загружаете, прежде чем отвезти вас в нужное место.
import org.apache.commons.lang.StringEscapeUtils;
import org.apache.http.cookie.Cookie;
import android.annotation.SuppressLint;
import android.webkit.CookieManager;
import android.webkit.CookieSyncManager;
import android.webkit.WebView;
import android.webkit.WebViewClient;
public class WebViewFragment {
private static final String BLANK_PAGE = "/blank.html"
private CookieSyncManager mSyncManager;
private CookieManager mCookieManager;
private String mTargetUrl;
private boolean mInitializedCookies;
private List<Cookie> mAllCookies;
public WebViewFragment(Context ctx) {
// We are still required to create an instance of Cookie/SyncManager.
mSyncManager = CookieSyncManager.createInstance(ctx);
mCookieManager = CookieManager.getInstance();
}
@SuppressLint("SetJavaScriptEnabled") public void loadWebView(
String url, List<Cookie> cookies, String domain) {
final WebView webView = ...
webView.setWebViewClient(new CookeWebViewClient());
webView.getSettings().setJavaScriptEnabled(true);
mInitializedCookies = false;
mTargetUrl = url;
mAllCookies = cookies;
// This is where the hack starts.
// Instead of loading the url, we load a blank page.
webView.loadUrl("http://" + domain + BLANK_PAGE);
}
public static String buildCookieString(final Cookie cookie) {
// You may want to add the secure flag for https:
// + "; secure"
// In case you wish to convert session cookies to have an expiration:
// + "; expires=Thu, 01-Jan-2037 00:00:10 GMT"
// Note that you cannot set the HttpOnly flag as we are using
// javascript to set the cookies.
return cookie.getName() + "=" + cookie.getValue()
+ "; path=" + cookie.getPath()
+ "; domain=" + cookie.getDomain()
};
public synchronized String generateCookieJavascript() {
StringBuilder javascriptCode = new StringBuilder();
javascriptCode.append("javascript:(function(){");
for (final Cookie cookie : mAllCookies) {
String cookieString = buildCookieString(cookie);
javascriptCode.append("document.cookie=\"");
javascriptCode.append(
StringEscapeUtils.escapeJavascriptString(cookieString));
javascriptCode.append("\";");
}
// We use javascript to load the next url because we do not
// receive an onPageFinished event when this code finishes.
javascriptCode.append("document.location=\"");
javascriptCode.append(
StringEscapeUtils.escapeJavascriptString(mTargetUrl));
javascriptCode.append("\";})();");
return javascriptCode.toString();
}
private class CookieWebViewClient extends WebViewClient {
@Override public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
if (!mInitializedCookies) {
mInitializedCookies = true;
// Run our javascript code now that the temp page is loaded.
view.loadUrl(generateCookieJavascript());
return;
}
}
}
}
Если вы доверяете домену, в котором находятся файлы cookie, вы можете уйти без apache commons, но вы должны понимать, что это может представлять риск XSS, если вы не будете осторожны.
Ответ 8
Это рабочий бит кода.
private void setCookie(DefaultHttpClient httpClient, String url) {
List<Cookie> cookies = httpClient.getCookieStore().getCookies();
if (cookies != null) {
CookieSyncManager.createInstance(context);
CookieManager cookieManager = CookieManager.getInstance();
cookieManager.setAcceptCookie(true);
for (int i = 0; i < cookies.size(); i++) {
Cookie cookie = cookies.get(i);
String cookieString = cookie.getName() + "=" + cookie.getValue();
cookieManager.setCookie(url, cookieString);
}
CookieSyncManager.getInstance().sync();
}
}
Здесь httpclient - это объект DefaultHttpClient, который вы использовали в запросе HttpGet/HttpPost. Также нужно убедиться, что имя файла cookie и его значение должны быть указаны
String cookieString = cookie.getName() + "=" + cookie.getValue();
setCookie будет устанавливать cookie для данного URL.
Ответ 9
Я волшебно решил все свои проблемы с файлом cookie с этой одной строкой в onCreate:
CookieHandler.setDefault(new CookieManager());
edit: он сегодня не работает.:( что за дерьмо, андроид.
Ответ 10
Об этом тоже говорилось. Вот что я сделал.
В моем LoginActivity внутри моей AsyncTask у меня есть следующее:
CookieStoreHelper.cookieStore = new BasicCookieStore();
BasicHttpContext localContext = new BasicHttpContext();
localContext.setAttribute(ClientContext.COOKIE_STORE, CookieStoreHelper.cookieStore);
HttpResponse postResponse = client.execute(httpPost,localContext);
CookieStoreHelper.sessionCookie = CookieStoreHelper.cookieStore.getCookies();
//WHERE CookieStoreHelper.sessionCookie - это еще один класс, содержащий переменную sessionCookie, определенную как файлы cookie списка; и cookieStore определяют как BasicCookieStore cookieStore;
Затем на моем фрагменте, где находится мой WebView, у меня есть следующее:
//DECLARE LIST OF COOKIE
List<Cookie> sessionCookie;
внутри моего метода или непосредственно перед установкой WebViewClient()
WebSettings settings = webView.getSettings();
settings.setJavaScriptEnabled(true);
webView.setScrollBarStyle(WebView.SCROLLBARS_OUTSIDE_OVERLAY);
sessionCookie = CookieStoreHelper.cookieStore.getCookies();
CookieSyncManager.createInstance(webView.getContext());
CookieSyncManager.getInstance().startSync();
CookieManager cookieManager = CookieManager.getInstance();
CookieManager.getInstance().setAcceptCookie(true);
if (sessionCookie != null) {
for(Cookie c: sessionCookie){
cookieManager.setCookie(CookieStoreHelper.DOMAIN, c.getName() + "=" + c.getValue());
}
CookieSyncManager.getInstance().sync();
}
webView.setWebViewClient(new WebViewClient() {
//AND SO ON, YOUR CODE
}
Быстрый совет: установите firebug на firefox или используйте консоль разработчика на Chrome и сначала проверьте свою веб-страницу, запишите Cookie и проверьте домен, чтобы вы могли его где-то сохранить и убедитесь, что вы правильно настроили правильный домен.
Изменить: отредактировал CookieStoreHelper.cookies в CookieStoreHelper.sessionCookie
Ответ 11
Мой рабочий код
public View onCreateView(...){
mWebView = (WebView) view.findViewById(R.id.webview);
WebSettings webSettings = mWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
...
...
...
CookieSyncManager.createInstance(mWebView.getContext());
CookieManager cookieManager = CookieManager.getInstance();
cookieManager.setAcceptCookie(true);
//cookieManager.removeSessionCookie(); // remove
cookieManager.removeAllCookie(); //remove
// Recommended "hack" with a delay between the removal and the installation of "Cookies"
SystemClock.sleep(1000);
cookieManager.setCookie("https://my.app.site.com/", "cookiename=" + value + "; path=/registration" + "; secure"); // ;
CookieSyncManager.getInstance().sync();
mWebView.loadUrl(sp.getString("url", "") + end_url);
return view;
}
Чтобы отладить запрос, "cookieManager.setCookie(....);" Я рекомендую вам просмотреть содержимое базы данных webviewCookiesChromium.db (хранится в "/data/data/my.app.webview/database"). Там вы можете увидеть правильные настройки.
Отключение "cookieManager.removeSessionCookie();" и/или "cookieManager.removeAllCookie();"
//cookieManager.removeSessionCookie();
// and/or
//cookieManager.removeAllCookie();"
Сравните установленное значение с теми, которые установлены браузером. Отрегулируйте запрос на установку куки до того, как "флаги" браузера не будут установлены, будет соответствовать тому, что вы решите. Я обнаружил, что запрос может быть "флаги":
// You may want to add the secure flag for https:
+ "; secure"
// In case you wish to convert session cookies to have an expiration:
+ "; expires=Thu, 01-Jan-2037 00:00:10 GMT"
// These flags I found in the database:
+ "; path=/registration"
+ "; domain=my.app.site.com"
Ответ 12
Пара комментариев (по крайней мере для API> = 21), которые я узнал из своего опыта и доставил мне головную боль:
-
http
и https
разные. Настройка файла cookie для http://www.example.com
отличается от настройки файла cookie для https://www.example.com
- Косая черта в конце URL также может иметь значение. В моем случае
https://www.example.com/
работает, но https://www.example.com
не работает. -
CookieManager.getInstance().setCookie
выполняет асинхронную операцию. Таким образом, если вы загрузите URL-адрес сразу после его установки, это не гарантирует, что файлы cookie будут уже записаны. Чтобы предотвратить непредвиденное и нестабильное поведение, используйте CookieManager # setCookie (URL-адрес строки, значение String, обратный вызов ValueCallback) () rel="nofollow noreferrer">ссылка) и начните загрузку URL-адреса после вызова обратного вызова.
Я надеюсь, что мои два цента сэкономят некоторое время у некоторых людей, чтобы вам не пришлось сталкиваться с такими же проблемами, как я.
Ответ 13
Я столкнулся с той же проблемой, и она решит эту проблему во всех версиях Android
private void setCookie() {
try {
CookieSyncManager.createInstance(context);
CookieManager cookieManager = CookieManager.getInstance();
cookieManager.setAcceptCookie(true);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
cookieManager.setCookie(Constant.BASE_URL, getCookie(), value -> {
String cookie = cookieManager.getCookie(Constant.BASE_URL);
CookieManager.getInstance().flush();
CustomLog.d("cookie", "cookie ------>" + cookie);
setupWebView();
});
} else {
cookieManager.setCookie(webUrl, getCookie());
new Handler().postDelayed(this::setupWebView, 700);
CookieSyncManager.getInstance().sync();
}
} catch (Exception e) {
CustomLog.e(e);
}
}
Ответ 14
Поиск на канале YouTube и получить ответ Мне нравится https://youtu.be/TUXui5ItBkM
Ответ 15
Не используйте ваш сырой URL
Вместо:
cookieManager.setCookie(myUrl, cookieString);
используйте это так:
cookieManager.setCookie("your url host", cookieString);