加载webView发送请求

本文介绍了一个iOS应用中使用UIWebView发起POST请求的方法。通过创建可变的URLRequest并设置HTTP方法为POST,同时添加了必要的头部信息如Content-Type等,并将参数字典转化为POST数据。此外还详细介绍了如何对POST数据进行编码处理。

  [self loadWebView:_webView withURLString:@"http://sjkdslfskdlnkndsnk" andPostDictionaryOrNil:_para];


- (void) loadWebView:(UIWebView *)theWebView withURLString:(NSString *)urlString andPostDictionaryOrNil:(NSDictionary *)postDictionary

{

    NSURL *url = [NSURL URLWithString:urlString];

    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url

                                                           cachePolicy:NSURLRequestReloadIgnoringCacheData

                                                       timeoutInterval:60.0];

    

    // DATA TO POST

    if(postDictionary) {

        NSString *postString = [self getFormDataString:postDictionary];

        NSData *postData = [postString dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES];

        

        

        [request setHTTPMethod:@"POST"];

        

        //       [request setValue:@"text/html;charset=utf-8" forHTTPHeaderField:@"Content­-Type"];

        [request addValue:@"IOS" forHTTPHeaderField:@"YUFU-TERMINAL-TYPE"];

        [request addValue:@"1.0.1" forHTTPHeaderField:@"YUFU-TERMINAL-VERSION"];

        [request setValue:@"application/x-www-form-urlencoded; charset=utf-8" forHTTPHeaderField:@"Content-Type"];

        [request setHTTPBody:postData];

    }

    

    [theWebView loadRequest:request];

}

- (NSString *)getFormDataString:(NSDictionary*)dictionary {

    if( ! dictionary) {

        return nil;

    }

    NSArray* keys = [dictionary allKeys];

    NSMutableString* resultString = [[NSMutableString alloc] init];

    for (int i = 0; i < [keys count]; i++) {

        NSString *key = [NSString stringWithFormat:@"%@", [keys objectAtIndex: i]];

        NSString *value = [NSString stringWithFormat:@"%@", [dictionary valueForKey: [keys objectAtIndex: i]]];

        

        NSString *encodedKey = [self escapeString:key];

        NSString *encodedValue = [self escapeString:value];

        

        NSString *kvPair = [NSString stringWithFormat:@"%@=%@", encodedKey, encodedValue];

        if(i > 0) {

            [resultString appendString:@"&"];

        }

        [resultString appendString:kvPair];

    }

    return resultString;

}

//对key和Value的数据进行 编码处理

- (NSString *)escapeString:(NSString *)string {

    if(string == nil || [string isEqualToString:@""]) {

        return @"";

    }

    NSString *outString = [NSString stringWithString:string];

    outString = [outString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

    

    // BUG IN stringByAddingPercentEscapesUsingEncoding

    // WE NEED TO DO several OURSELVES

    outString = [self replace:outString lookFor:@"&" replaceWith:@"%26"];

    outString = [self replace:outString lookFor:@"?" replaceWith:@"%3F"];

    outString = [self replace:outString lookFor:@"=" replaceWith:@"%3D"];

    outString = [self replace:outString lookFor:@"+" replaceWith:@"%2B"];

    outString = [self replace:outString lookFor:@";" replaceWith:@"%3B"];

    

    return outString;

}


//去掉空格和特殊字符

- (NSString *)replace:(NSString *)originalString lookFor:(NSString *)find replaceWith:(NSString *)replaceWith {

    if ( ! originalString || ! find) {

        return originalString;

    }

    

    if( ! replaceWith) {

        replaceWith = @"";

    }

    

    NSMutableString *mstring = [NSMutableString stringWithString:originalString];

    NSRange wholeShebang = NSMakeRange(0, [originalString length]);

    

    [mstring replaceOccurrencesOfString: find

                             withString: replaceWith

                                options: 0

                                  range: wholeShebang];

    

    return [NSString stringWithString: mstring];

}







<think> 首先,用户的问题是基于之前的引用和上下文。用户提供的引用是关于在Android和JavaFx的WebView中添加请求头的方法。用户说:“我想查找在WebView中添加请求头的方法 请问WebView添加请求头的实现方法”。所以,我需要根据这些引用提供相关信息。 关键引用: - 引用[1]: 提到在Android WebView中初始化时添加header请求头和token,但ajax请求时header带不过去。 - 引用[2]: 提到使用webView.loadUrl(url, header)添加请求头只在一级页面生效,二级页面失效;提到同步cookie。 - 引用[3]: 关于Android拦截WebView加载url和获取POST请求参数。 - 引用[4]: 关于JavaFx WebView通过prepareConnection方法添加自定义请求头。 用户的需求是“WebView添加请求头的实现方法”,但引用中提到了多个平台:Android和JavaFx。用户可能在Android上下文中,因为引用[1]-[3]都是Android相关的,引用[4]是JavaFx。我应该优先考虑Android的实现,因为引用更相关。 系统级指令: - 所有行内数学表达式用$...$(但这里不需要数学,所以可能不适用)。 - 独立公式用$$...$$(同样不适用)。 - LaTeX语法正确(确保代码块正确)。 - 使用中文回答。 - 生成相关问题。 - 回答中引用的段落末尾自然地添加引用标识,如[^1]。 回答结构: - 清晰、逐步解决问题。 - 参考用户上一次问题和我的回答(但这是第一次交互,所以基于当前)。 - 用户说:“上述引用仅供参考,并不是用户真正的需求,请尽可能多的参考用户上一次的问题和你的回答。” 用户提到“用户上一次的问题”,但在这个对话中,这是第一次用户消息。可能用户在引用之前的上下文,但在这个模拟中,我应该忽略“用户上一次的问题”,因为没有先前消息。专注于当前问题。 用户真正的需求:在WebView中添加请求头。根据引用,问题在于添加请求头在页面跳转或ajax请求时不生效。 关键点: - 在Android WebView中,使用loadUrl(url, headers)添加请求头只对初始页面有效,对其他页面或ajax请求无效。 - 引用[2]提到同步cookie可能是一个方法。 - 引用[3]提到拦截WebView请求来修改参数。 - 引用[4]展示JavaFx中通过覆盖prepareConnection方法添加请求头。 对于Android WebView- 解决方案:为了确保所有请求带有header,需要拦截所有请求并添加header。可以使用WebViewClient并覆盖shouldOverrideUrlLoading或shouldInterceptRequest方法。 - 在Android API 21+中,shouldInterceptRequest方法可以用来拦截并修改请求。 实现步骤(针对Android): 1. 创建一个自定义的WebViewClient。 2. 覆盖shouldInterceptRequest方法。 3. 在这个方法中,创建一个新的WebResourceResponse或修改请求。 4. 添加自定义header,如Authorization token。 代码示例:参考引用,我可以提供一个简单的代码片段。 类似引用[4]的JavaFx方法:在Android中,没有prepareConnection,但有shouldInterceptRequest。 用户提到“WebView”,可能泛指,但引用主要是Android。我应该专注于Android,因为引用更相关。 回答结构: - 先解释问题。 - 给出解决方法。 - 提供代码示例。 - 自然地添加引用标识。 - 最后生成相关问题。 自然地添加引用:在引用相关内容时,末尾添加[^n]。 例如,当提到引用[1]的问题时,添加[^1]。 完整回答: 1. 引言:解释在WebView中添加请求头的问题。 2. 解决方案:描述如何通过拦截请求来实现。 3. 代码示例:提供Android代码。 4. 注意事项:比如对ajax请求的处理。 5. 相关问题:生成相关问题。 生成相关问题: - 用户指令:生成相关问题。 - 示例中,有§§相关问题§§部分。 - 生成2-3个相关问题基于上下文。 相关问题想法: 1. 如何处理WebView中的ajax请求添加header? 2. WebView添加header时的兼容性问题? 3. 其他平台如JavaFx如何实现? 4. 同步cookie的方法? 参考用户上次问题:但这里没有,所以基于当前。 最终回答大纲: - 回答问题。 - 代码块。 - 相关问题。 确保中文。 </think> ### WebView添加请求头的实现方法 在Android WebView中添加请求头时,常见问题是:使用`loadUrl(url, headers)`方法仅在初始页面加载时生效,而对于页面跳转(如a标签)或ajax请求(异步JavaScript请求),请求头无法传递,导致token或自定义header丢失[^1][^2]。根本原因是这些方法只针对首次加载生效,后续请求未携带自定义header。为了解决这个问题,需要拦截所有WebView请求并动态添加header。以下是基于Android平台的逐步实现方法(API 21+),使用WebViewClient的`shouldInterceptRequest`方法拦截并修改请求。注意:该方法适用于HTTP/HTTPS请求,但需处理兼容性和安全机制(如CORS)。 #### 步骤详解 1. **创建自定义WebViewClient**:覆盖`shouldInterceptRequest`方法拦截请求。 2. **添加请求头**:在拦截时,构造新的请求对象并注入自定义header(如token)。 3. **处理ajax请求**:此方法能捕获所有类型的请求(包括ajax),确保header一致传递。 4. **初始化WebView**:在Activity或Fragment中设置自定义WebViewClient。 #### 代码实现示例 以下是一个完整的Android Kotlin代码示例(Java类似)。此示例添加一个Authorization header(token),并处理所有页面和ajax请求: ```kotlin import android.os.Bundle import android.webkit.WebResourceRequest import android.webkit.WebResourceResponse import android.webkit.WebView import android.webkit.WebViewClient import androidx.appcompat.app.AppCompatActivity import java.net.URL import java.util.HashMap class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val webView = WebView(this) setContentView(webView) // 设置自定义WebViewClient以拦截请求 webView.webViewClient = object : WebViewClient() { // 覆盖shouldInterceptRequest方法(API 21+) override fun shouldInterceptRequest( view: WebView, request: WebResourceRequest ): WebResourceResponse? { try { val url = request.url.toString() // 检查是否为需要添加header的请求(例如,排除静态资源) if (url.startsWith("http") && !url.contains(".css") && !url.contains(".js")) { val modifiedHeaders = HashMap<String, String>(request.requestHeaders) // 添加自定义header,例如Authorization token modifiedHeaders["Authorization"] = "Bearer YOUR_TOKEN_HERE" modifiedHeaders["Custom-Header"] = "value" // 构造新的请求对象(伪代码:实际需使用OkHttp或HttpURLConnection处理) // 注意:实际实现中,这里需发送请求并获取响应(简化示例) // 以下为示意逻辑,真实项目需使用网络库处理 val urlObj = URL(url) val connection = urlObj.openConnection().apply { modifiedHeaders.forEach { (key, value) -> setRequestProperty(key, value) } } // 获取响应流(实际中需处理输入流) val responseStream = connection.getInputStream() val mimeType = connection.contentType val encoding = connection.contentEncoding ?: "UTF-8" // 返回WebResourceResponse return WebResourceResponse(mimeType, encoding, responseStream) } } catch (e: Exception) { e.printStackTrace() } // 默认行为:不修改请求 return super.shouldInterceptRequest(view, request) } } // 加载初始URL(可选添加初始header) webView.loadUrl("https://example.com") } } ``` #### 关键注意事项 - **兼容性**:`shouldInterceptRequest`需要Android 5.0 (API 21)及以上。对于旧版本(API < 21),可使用`shouldOverrideUrlLoading`拦截导航请求,但无法处理ajax[^2][^3]。 - **性能影响**:频繁拦截请求可能降低WebView性能,建议仅对特定URL添加header。 - **安全机制**:添加header时需处理HTTPS和CORS(跨域资源共享),避免被浏览器阻止[^1]。 - **其他平台**:如JavaFx WebView,可通过覆盖`prepareConnection`方法添加请求头(类似引用[4]的实现)[^4]。 - **备选方案**:如果拦截复杂,可考虑同步cookie作为替代(使用`CookieManager`),但header更灵活[^2]。 此方法在Android WebView中能有效解决ajax和页面跳转时header丢失的问题。如果遇到具体错误,提供更多细节可进一步优化。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值