【关键字】
Web组件 / html / 跨域 / fetch请求 /onInterceptRequest
【问题描述】
问题一:
使用web组件加载本地html时,如何解决跨域问题和fetch请求?
问题二:
onInterceptRequest方法会拦截所有的请求,然后在onInterceptRequest的回调中使用native的方法再去请求对应的资源,拿到结果然后再return回去,确实这样可以解决跨越问题,那是将所有的请求都通过自己的方法去代理实现了。可能只需要对个别url做代理请求,其他的走默认就好。但是只要使用onInterceptRequest就必须自己代理所有请求。
问题三:
scheme1: web_webview.WebCustomScheme = {schemeName: "name1", isSupportCORS: true, isSupportFetch: true}这个和onInterceptRequest如何配合使用呢? 你的Demo中就只有·if (event.request.getRequestUrl().match('name1'))·,这一段起了什么作用?web_webview.WebviewController.customizeSchemes([this.scheme1, this.scheme2, this.scheme3])。这又和onInterceptRequest有什么关系?
【解决方案】
示例代码:
// xxx.ets
import web_webview from '@ohos.web.webview';
import business_error from '@ohos.base';
@Entry
@Component
struct WebComponent {
controller: web_webview.WebviewController = new web_webview.WebviewController();
responseweb: WebResourceResponse = new WebResourceResponse()
scheme1: web_webview.WebCustomScheme = {schemeName: "name1", isSupportCORS: true, isSupportFetch: true}
scheme2: web_webview.WebCustomScheme = {schemeName: "name2", isSupportCORS: true, isSupportFetch: true}
scheme3: web_webview.WebCustomScheme = {schemeName: "name3", isSupportCORS: true, isSupportFetch: true}
heads:Header[] = new Array()
aboutToAppear():void {
try {
web_webview.WebviewController.customizeSchemes([this.scheme1, this.scheme2, this.scheme3])
} catch(error) {
let e:business_error.BusinessError = error as business_error.BusinessError;
console.error(`ErrorCode: ${e.code}, Message: ${e.message}`);
}
}
build() {
Column() {
Web({ src: 'name1'+'www.example.com', controller: this.controller })
.onInterceptRequest((event) => {
if (event) {
console.log('urlsda:' + event.request.getRequestUrl())
if (event.request.getRequestUrl().match('name1')){
let head1:Header = {
headerKey:"Connection",
headerValue:"keep-alive"
}
let head2:Header = {
headerKey:"Cache-Control",
headerValue:"no-cache"
}
let length = this.heads.push(head1)
length = this.heads.push(head2)
this.responseweb.setResponseHeader(this.heads)
this.responseweb.setResponseData($rawfile('KuaYu.html'))
this.responseweb.setResponseEncoding('utf-8')
this.responseweb.setResponseMimeType('text/html')
this.responseweb.setResponseCode(200)
this.responseweb.setReasonMessage('OK')console.log('urlsda:' + event.request.getRequestUrl())
问题一:
可以使用customizeSchemes接口来自定义协议解决跨域问题和fetch请求。
参考连接:
问题二:
Web组件中onInterceptRequest对于不需要拦截的url可以直接在接口中返回null,需要拦截的重写返回值。
问题三:
customizeSchemes方法的作用是对Web内核赋予对自定义协议url的跨域请求与fetch请求的权限,当Web在跨域fetch自定义协议url时,该fetch请求可被onInterceptRequest事件接口所拦截,从而开发者可以进一步处理该请求。
web_webview.WebviewController.customizeSchemes([{schemeName: "abc", isSupportCors: true, isSupportFetch: true}]); 通过customizeSchemes接口,isSupportCORS表示是否支持跨域请求。schemeName表示自定义协议名称。
根据web组件解决跨域问题的规格,拦截方法的作用就是在拦截到经过拼接自定义协议的url后,在拦截方法里使用WebResourceResponse 接口加载有跨域问题的页面,这样就能解决跨域问题。
总的来说onInterceptRequest起到一个拦截自定义协议后return有跨域问题的页面来解决跨域。