IMYWebLoader(WKHookAjax)是解决hook ajax请求参数丢失问题的开源框架。

解析:https://www.jianshu.com/p/4c33d6b05c4c

当把它加入到蚂蚁框架中会出现一些问题也会解决一些问题。

1.比如蚂蚁框架引入社保sdk:社保sdk有自己的wkwebview展示与ajax请求。加到蚂蚁工程里,社保sdk的webview发请求就被拦截了,按照蚂蚁框架的思路拦截后将走的是

EESBWebJSVCHandler.m- (void)userContentController:(nonnull WKUserContentController *)arg1 didReceiveScriptMessageS:(nonnull WKScriptMessage *)arg2;{if( [arg2.name isEqualToString:@"PSDXMLHTTPREQUESTMESSAGE"]){//用于三方页面ajax请求
}
}

这个方法发请求与返回数据。但社保sdk是没有加载h5_message_channel.js的,而且也没有注册PSDXMLHTTPREQUESTMESSAGE,也没有实现原生请求的方法,所以社保webview就出现了问题。

解决这个问题的办法:

1.进社保前unregisterSchemeForCustomProtocol: 出社保后registerSchemeForCustomProtocol:

2.使用IMYWebLoader 将请求再次拦截并正常返回

代码是 [self.userContentController imy_installHookAjax];

需要判断社保webview

.h
#import <WebKit/WebKit.h>NS_ASSUME_NONNULL_BEGIN@interface WKWebViewConfiguration (PC)@endNS_ASSUME_NONNULL_END
.m#import "WKWebViewConfiguration+PC.h"
#import <objc/runtime.h>
#import "IMYWebLoader.h"@implementation WKWebViewConfiguration (PC)
+ (void)load{{Method originalMethod = class_getInstanceMethod([NSClassFromString(@"WKWebViewConfiguration") class], @selector(setUserContentController:));Method swizzledMethod = class_getInstanceMethod([self class], @selector(setUserContentControllerS:));method_exchangeImplementations(originalMethod, swizzledMethod);}
}
-(void)setUserContentControllerS:(WKUserContentController *)userContentController{[self setUserContentControllerS:userContentController];
if(isSdk){[self.userContentController imy_installHookAjax];
}}

2.引入IMYWebLoader后蚂蚁容器加载离线包都没有问题。

3.引入IMYWebLoader后如果把蚂蚁容器的userContentController也imy_installHookAjax了,会影响到“蚂蚁容器加载三方链接”。

原因:因为蚂蚁框架ajax请求已经被原生PSDXMLHTTPREQUESTMESSAGE拦截替换了而且得由他返回数据,IMYWebLoader再次拦截后出现问题。

与PSDXMLHTTPREQUESTMESSAGE相关的js文件是h5_message_channel.js

h5_message_channel.js(function(){var tkReplace = "NEBULA_BRIDGE_JS_REPLACE_STRING";/**********************js fetch************************/
(function(self) {'use strict';var support = {searchParams: 'URLSearchParams' in self,iterable: 'Symbol' in self && 'iterator' in Symbol,blob: 'FileReader' in self && 'Blob' in self && (function() {try {new Blob()return true} catch(e) {return false}})(),formData: 'FormData' in self,arrayBuffer: 'ArrayBuffer' in self}if (support.arrayBuffer) {var viewClasses = ['[object Int8Array]','[object Uint8Array]','[object Uint8ClampedArray]','[object Int16Array]','[object Uint16Array]','[object Int32Array]','[object Uint32Array]','[object Float32Array]','[object Float64Array]']var isDataView = function(obj) {return obj && DataView.prototype.isPrototypeOf(obj)}var isArrayBufferView = ArrayBuffer.isView || function(obj) {return obj && viewClasses.indexOf(Object.prototype.toString.call(obj)) > -1}}function normalizeName(name) {if (typeof name !== 'string') {name = String(name)}if (/[^a-z0-9\-#$%&'*+.\^_`|~]/i.test(name)) {throw new TypeError('Invalid character in header field name')}return name.toLowerCase()}function normalizeValue(value) {if (typeof value !== 'string') {value = String(value)}return value}// Build a destructive iterator for the value listfunction iteratorFor(items) {var iterator = {next: function() {var value = items.shift()return {done: value === undefined, value: value}}}if (support.iterable) {iterator[Symbol.iterator] = function() {return iterator}}return iterator}function Headers(headers) {this.map = {}if (headers instanceof Headers) {headers.forEach(function(value, name) {this.append(name, value)}, this)} else if (Array.isArray(headers)) {headers.forEach(function(header) {this.append(header[0], header[1])}, this)} else if (headers) {Object.getOwnPropertyNames(headers).forEach(function(name) {this.append(name, headers[name])}, this)}}Headers.prototype.append = function(name, value) {name = normalizeName(name)value = normalizeValue(value)var oldValue = this.map[name]this.map[name] = oldValue ? oldValue+','+value : value}Headers.prototype['delete'] = function(name) {delete this.map[normalizeName(name)]}Headers.prototype.get = function(name) {name = normalizeName(name)return this.has(name) ? this.map[name] : null}Headers.prototype.has = function(name) {return this.map.hasOwnProperty(normalizeName(name))}Headers.prototype.set = function(name, value) {this.map[normalizeName(name)] = normalizeValue(value)}Headers.prototype.forEach = function(callback, thisArg) {for (var name in this.map) {if (this.map.hasOwnProperty(name)) {callback.call(thisArg, this.map[name], name, this)}}}Headers.prototype.keys = function() {var items = []this.forEach(function(value, name) { items.push(name) })return iteratorFor(items)}Headers.prototype.values = function() {var items = []this.forEach(function(value) { items.push(value) })return iteratorFor(items)}Headers.prototype.entries = function() {var items = []this.forEach(function(value, name) { items.push([name, value]) })return iteratorFor(items)}if (support.iterable) {Headers.prototype[Symbol.iterator] = Headers.prototype.entries}function consumed(body) {if (body.bodyUsed) {return Promise.reject(new TypeError('Already read'))}body.bodyUsed = true}function fileReaderReady(reader) {return new Promise(function(resolve, reject) {reader.onload = function() {resolve(reader.result)}reader.onerror = function() {reject(reader.error)}})}function readBlobAsArrayBuffer(blob) {var reader = new FileReader()var promise = fileReaderReady(reader)reader.readAsArrayBuffer(blob)return promise}function readBlobAsText(blob) {var reader = new FileReader()var promise = fileReaderReady(reader)reader.readAsText(blob)return promise}function readArrayBufferAsText(buf) {var view = new Uint8Array(buf)var chars = new Array(view.length)for (var i = 0; i < view.length; i++) {chars[i] = String.fromCharCode(view[i])}return chars.join('')}function bufferClone(buf) {if (buf.slice) {return buf.slice(0)} else {var view = new Uint8Array(buf.byteLength)view.set(new Uint8Array(buf))return view.buffer}}function Body() {this.bodyUsed = falsethis._initBody = function(body) {this._bodyInit = bodyif (!body) {this._bodyText = ''} else if (typeof body === 'string') {this._bodyText = body} else if (support.blob && Blob.prototype.isPrototypeOf(body)) {this._bodyBlob = body} else if (support.formData && FormData.prototype.isPrototypeOf(body)) {this._bodyFormData = body} else if (support.searchParams && URLSearchParams.prototype.isPrototypeOf(body)) {this._bodyText = body.toString()} else if (support.arrayBuffer && support.blob && isDataView(body)) {this._bodyArrayBuffer = bufferClone(body.buffer)// IE 10-11 can't handle a DataView body.this._bodyInit = new Blob([this._bodyArrayBuffer])} else if (support.arrayBuffer && (ArrayBuffer.prototype.isPrototypeOf(body) || isArrayBufferView(body))) {this._bodyArrayBuffer = bufferClone(body)} else {throw new Error('unsupported BodyInit type')}if (!this.headers.get('content-type')) {if (typeof body === 'string') {this.headers.set('content-type', 'text/plain;charset=UTF-8')} else if (this._bodyBlob && this._bodyBlob.type) {this.headers.set('content-type', this._bodyBlob.type)} else if (support.searchParams && URLSearchParams.prototype.isPrototypeOf(body)) {this.headers.set('content-type', 'application/x-www-form-urlencoded;charset=UTF-8')}}}if (support.blob) {this.blob = function() {var rejected = consumed(this)if (rejected) {return rejected}if (this._bodyBlob) {return Promise.resolve(this._bodyBlob)} else if (this._bodyArrayBuffer) {return Promise.resolve(new Blob([this._bodyArrayBuffer]))} else if (this._bodyFormData) {throw new Error('could not read FormData body as blob')} else {return Promise.resolve(new Blob([this._bodyText]))}}this.arrayBuffer = function() {if (this._bodyArrayBuffer) {return consumed(this) || Promise.resolve(this._bodyArrayBuffer)} else {return this.blob().then(readBlobAsArrayBuffer)}}}this.text = function() {var rejected = consumed(this)if (rejected) {return rejected}if (this._bodyBlob) {return readBlobAsText(this._bodyBlob)} else if (this._bodyArrayBuffer) {return Promise.resolve(readArrayBufferAsText(this._bodyArrayBuffer))} else if (this._bodyFormData) {throw new Error('could not read FormData body as text')} else {return Promise.resolve(this._bodyText)}}if (support.formData) {this.formData = function() {return this.text().then(decode)}}this.json = function() {return this.text().then(JSON.parse)}return this}// HTTP methods whose capitalization should be normalizedvar methods = ['DELETE', 'GET', 'HEAD', 'OPTIONS', 'POST', 'PUT']function normalizeMethod(method) {var upcased = method.toUpperCase()return (methods.indexOf(upcased) > -1) ? upcased : method}function Request(input, options) {options = options || {}var body = options.bodyif (input instanceof Request) {if (input.bodyUsed) {throw new TypeError('Already read')}this.url = input.urlthis.credentials = input.credentialsif (!options.headers) {this.headers = new Headers(input.headers)}this.method = input.methodthis.mode = input.modeif (!body && input._bodyInit != null) {body = input._bodyInitinput.bodyUsed = true}} else {this.url = String(input)}this.credentials = options.credentials || this.credentials || 'omit'if (options.headers || !this.headers) {this.headers = new Headers(options.headers)}this.method = normalizeMethod(options.method || this.method || 'GET')this.mode = options.mode || this.mode || nullthis.referrer = nullif ((this.method === 'GET' || this.method === 'HEAD') && body) {throw new TypeError('Body not allowed for GET or HEAD requests')}this._initBody(body)}Request.prototype.clone = function() {return new Request(this, { body: this._bodyInit })}function decode(body) {var form = new FormData()body.trim().split('&').forEach(function(bytes) {if (bytes) {var split = bytes.split('=')var name = split.shift().replace(/\+/g, ' ')var value = split.join('=').replace(/\+/g, ' ')form.append(decodeURIComponent(name), decodeURIComponent(value))}})return form}function parseHeaders(rawHeaders) {var headers = new Headers()// Replace instances of \r\n and \n followed by at least one space or horizontal tab with a space// https://tools.ietf.org/html/rfc7230#section-3.2var preProcessedHeaders = rawHeaders.replace(/\r?\n[\t ]+/g, ' ')preProcessedHeaders.split(/\r?\n/).forEach(function(line) {var parts = line.split(':')var key = parts.shift().trim()if (key) {var value = parts.join(':').trim()headers.append(key, value)}})return headers}Body.call(Request.prototype)function Response(bodyInit, options) {if (!options) {options = {}}this.type = 'default'this.status = options.status === undefined ? 200 : options.statusthis.ok = this.status >= 200 && this.status < 300this.statusText = 'statusText' in options ? options.statusText : 'OK'this.headers = new Headers(options.headers)this.url = options.url || ''this._initBody(bodyInit)}Body.call(Response.prototype)Response.prototype.clone = function() {return new Response(this._bodyInit, {status: this.status,statusText: this.statusText,headers: new Headers(this.headers),url: this.url})}Response.error = function() {var response = new Response(null, {status: 0, statusText: ''})response.type = 'error'return response}var redirectStatuses = [301, 302, 303, 307, 308]Response.redirect = function(url, status) {if (redirectStatuses.indexOf(status) === -1) {throw new RangeError('Invalid status code')}return new Response(null, {status: status, headers: {location: url}})}self.Headers = Headersself.Request = Requestself.Response = Responseself.fetch = function(input, init) {return new Promise(function(resolve, reject) {var request = new Request(input, init)var xhr = new XMLHttpRequest()xhr.onload = function() {var options = {status: xhr.status,statusText: xhr.statusText,headers: parseHeaders(xhr.getAllResponseHeaders() || '')}options.url = 'responseURL' in xhr ? xhr.responseURL : options.headers.get('X-Request-URL')var body = 'response' in xhr ? xhr.response : xhr.responseTextresolve(new Response(body, options))}xhr.onerror = function() {reject(new TypeError('Network request failed'))}xhr.ontimeout = function() {reject(new TypeError('Network request failed'))}xhr.open(request.method, request.url, true)if (request.credentials === 'include') {xhr.withCredentials = true} else if (request.credentials === 'omit') {xhr.withCredentials = false}if ('responseType' in xhr && support.blob) {xhr.responseType = 'blob'}request.headers.forEach(function(value, name) {xhr.setRequestHeader(name, value)})xhr.send(typeof request._bodyInit === 'undefined' ? null : request._bodyInit)})}self.fetch.polyfill = true
})(typeof self !== 'undefined' ? self : this);/**********************from serializes************************/
(function(){// get successful control from form and assemble into object// http://www.w3.org/TR/html401/interact/forms.html#h-17.13.2// types which indicate a submit action and are not successful controls// these will be ignoredvar k_r_submitter = /^(?:button|image|reset|file)$/i;// node names which could be successful controlsvar k_r_success_contrls = /^(?:input|select|textarea|keygen)/i;// Matches bracket notation.var brackets = /(\[[^\[\]]*\])/g;// serializes form fields// @param form MUST be an HTMLForm element// @param options is an optional argument to configure the serialization. Default output// with no options specified is a url encoded string//    - hash: [true | false] Configure the output type. If true, the output will//    be a js object.//    - serializer: [function] Optional serializer function to override the default one.//    The function takes 3 arguments (result, key, value) and should return new result//    hash and url encoded str serializers are provided with this module//    - disabled: [true | false]. If true serialize disabled fields.//    - empty: [true | false]. If true serialize empty fieldsfunction serialize(form, options) {if (typeof options != 'object') {options = { hash: !!options };}else if (options.hash === undefined) {options.hash = true;}var result = (options.hash) ? {} : '';var serializer = options.serializer || ((options.hash) ? hash_serializer : str_serialize);var elements = form && form.elements ? form.elements : [];//Object store each radio and set if it's empty or notvar radio_store = Object.create(null);for (var i=0 ; i<elements.length ; ++i) {var element = elements[i];// ingore disabled fieldsif ((!options.disabled && element.disabled) || !element.name) {continue;}// ignore anyhting that is not considered a success fieldif (!k_r_success_contrls.test(element.nodeName) ||k_r_submitter.test(element.type)) {continue;}if (/submit/.test(element.type) && (document.activeElement !== element && window.lastClickElement !== element)) {continue;}var key = element.name;var val = element.value;// we can't just use element.value for checkboxes cause some browsers lie to us// they say "on" for value when the box isn't checkedif ((element.type === 'checkbox' || element.type === 'radio') && !element.checked) {val = undefined;}// If we want empty elementsif (options.empty) {// for checkboxif (element.type === 'checkbox' && !element.checked) {continue;}// for radioif (element.type === 'radio' && !element.checked) {continue;}// for radioif (element.type === 'radio') {if (!radio_store[element.name] && !element.checked) {radio_store[element.name] = false;}else if (element.checked) {radio_store[element.name] = true;}}// if options empty is true, continue only if its radioif (val == undefined && element.type == 'radio') {continue;}}else {// value-less fields are ignored unless options.empty is trueif (!val) {continue;}}// multi select boxesif (element.type === 'select-multiple') {val = [];var selectOptions = element.options;var isSelectedOptions = false;for (var j=0 ; j<selectOptions.length ; ++j) {var option = selectOptions[j];var allowedEmpty = options.empty && !option.value;var hasValue = (option.value || allowedEmpty);if (option.selected && hasValue) {isSelectedOptions = true;result = serializer(result, key, option.value);}}// // Serialize if no selected options and options.empty is true// if (!isSelectedOptions && options.empty) {//     result = serializer(result, key, '');// }continue;}result = serializer(result, key, val);}// Check for all empty radio buttons and serialize them with key=""if (options.empty) {for (var key in radio_store) {if (!radio_store[key]) {result = serializer(result, key, '');}}}return result;}function parse_keys(string) {var keys = [];var prefix = /^([^\[\]]*)/;var children = new RegExp(brackets);var match = prefix.exec(string);if (match[1]) {keys.push(match[1]);}while ((match = children.exec(string)) !== null) {keys.push(match[1]);}return keys;}function hash_assign(result, keys, value) {if (keys.length === 0) {result = value;return result;}var key = keys.shift();var between = key.match(/^\[(.+?)\]$/);if (key === '[]') {result = result || [];if (Array.isArray(result)) {result.push(hash_assign(null, keys, value));}else {// This might be the result of bad name attributes like "[][foo]",// in this case the original `result` object will already be// assigned to an object literal. Rather than coerce the object to// an array, or cause an exception the attribute "_values" is// assigned as an array.result._values = result._values || [];result._values.push(hash_assign(null, keys, value));}return result;}// Key is an attribute name and can be assigned directly.if (!between) {result[key] = hash_assign(result[key], keys, value);}else {var string = between[1];// +var converts the variable into a number// better than parseInt because it doesn't truncate away trailing// letters and actually fails if whole thing is not a numbervar index = +string;// If the characters between the brackets is not a number it is an// attribute name and can be assigned directly.if (isNaN(index)) {result = result || {};result[string] = hash_assign(result[string], keys, value);}else {result = result || [];result[index] = hash_assign(result[index], keys, value);}}return result;}// Object/hash encoding serializer.function hash_serializer(result, key, value) {var matches = key.match(brackets);// Has brackets? Use the recursive assignment function to walk the keys,// construct any missing objects in the result tree and make the assignment// at the end of the chain.// not to change filename so use falseif (false) {var keys = parse_keys(key);hash_assign(result, keys, value);}else {// Non bracket notation can make assignments directly.var existing = result[key];// If the value has been assigned already (for instance when a radio and// a checkbox have the same name attribute) convert the previous value// into an array before pushing into it.//// NOTE: If this requirement were removed all hash creation and// assignment could go through `hash_assign`.if (existing) {if (!Array.isArray(existing)) {result[key] = [ existing ];}result[key].push(value);}else {result[key] = value;}}return result;}// urlform encoding serializerfunction str_serialize(result, key, value) {// encode newlines as \r\n cause the html spec says sovalue = value.replace(/(\r)?\n/g, '\r\n');value = encodeURIComponent(value);// spaces should be '+' rather than '%20'.value = value.replace(/%20/g, '+');return result + (result ? '&' : '') + encodeURIComponent(key) + '=' + value;}window.NebulaSerialize = serialize;
})();(function(){var ktnebula = tkReplace;var webkit = window.webkit;var postMessage = webkit.messageHandlers.PSDXMLHTTPREQUESTMESSAGE.postMessage;var PSDXMLHTTPREQUESTMESSAGE = webkit.messageHandlers.PSDXMLHTTPREQUESTMESSAGE;function safeCallMessage(message){return postMessage.apply(PSDXMLHTTPREQUESTMESSAGE,[message]);}/**********************rewrite cookie************************/var cookieOriginSetter = document.__lookupSetter__('cookie'),cookieOriginGetter = document.__lookupGetter__('cookie');var NebulaUpdateCookies;if (cookieOriginSetter && cookieOriginGetter) {Object.defineProperty(document, 'cookie', {set: function(cookstr) {if (typeof cookstr !== 'string') {return;};var message = {};message[msgType] = "cookie";message["cookie"] = cookstr;message["url"] = document.location.href;message["msgKt"] = ktnebula;//iOS 10 and iOS 11 if call this on unload event,window.webkit can be nullif (webkit && webkit.messageHandlers && webkit.messageHandlers.PSDXMLHTTPREQUESTMESSAGE && webkit.messageHandlers.PSDXMLHTTPREQUESTMESSAGE.postMessage) {safeCallMessage(message);}cookieOriginSetter.apply(document,[cookstr]);},get: function(){return cookieOriginGetter.apply(document,[]);},configurable: false});}else{if (window.SHOULDNEBULADORWC) {var cookieNameMap = {Version: 'version',Name: 'name',Value: 'value',MaxAge: 'maxAge',MaxAgeDate: 'maxAgeDate',ExpiresDate: 'expiresDate',Domain: 'domain',Path: 'path',Secure: 'secure',HttpOnly: 'httpOnly'}function idIPAddress(address) {return /^(d+).(d+).(d+).(d+)$/.test(address);};function isRegExp(value, rule) {if (rule && typeof rule === "string" && rule.length > 0) {var reg = new RegExp(rule + '$');return reg.test(value);}else{return false;}};function hasPrefix(value, rule){if (rule.length > 0) {var reg = new RegExp("^" + rule);return reg.test(value);}else{return false;}}function domianMatch(value){var hostMatch = (value && isRegExp(document.location.hostname.toLowerCase(),value));var isRootDomain = false;var p = value.split('.');var q = p.length;if (q == 2 || (q == 3 && p[1] === 'com')) {isRootDomain = true;}return (hostMatch && !isRootDomain);}function getPath() {var k = document.location.pathname;var l = k.lastIndexOf('/');var result = k.substring(0, l);if (result.length == 0) {return "/";}else{return result;}};var cookieStore = [];function isCookieExpired(cookieObj) {var l = typeof cookieObj[cookieNameMap.MaxAgeDate] == 'object';if (l && cookieObj[cookieNameMap.MaxAge] <= 0) {return true} else {if (l) {return cookieObj[cookieNameMap.MaxAgeDate] < new Date()} else {if (typeof cookieObj[cookieNameMap.ExpiresDate] == 'object') {return cookieObj[cookieNameMap.ExpiresDate] < new Date()} else {return false}}}};function getCookieStr() {var length = cookieStore.length,index = 0, item, result = [];for (; index < length; index ++) {item = cookieStore[index];if (!isCookieExpired(item)) {result.push(item[cookieNameMap.Name] + '=' + item[cookieNameMap.Value])}};return result.join('; ')};function updateAllCookie(cookieObj) {var length = cookieStore.length,index=0, item, result = [];for (; index < length; index ++) {item = cookieStore[index];if (!(item[cookieNameMap.Name] === cookieObj[cookieNameMap.Name] && item[cookieNameMap.Path] === cookieObj[cookieNameMap.Path] && item[cookieNameMap.Domain] === cookieObj[cookieNameMap.Domain])) {result.push(item);}};cookieStore = result;};function updateCookie(cookieObj) {//if path not match just returnvar cookiePath = cookieObj[cookieNameMap.Path];var isPrefixWithCookiePath = (hasPrefix(getPath(),cookiePath) || hasPrefix(document.location.pathname,cookiePath));if (!isPrefixWithCookiePath) {return;}updateAllCookie(cookieObj);cookieStore.unshift(cookieObj);};function parseOthers(name, value, cookieObj) {var name = name.toLowerCase();var o;value = value.trim();switch (name) {case 'expires':{var date = new Date(value);if (!isNaN(date.getTime())) {cookieObj[cookieNameMap.ExpiresDate] = date;}};break;case 'max-age':{if (!isNaN(value)) {var p = Number(parseInt(value));var q = new Date();q.setTime(q.getTime() + p * 1000);cookieObj[cookieNameMap.MaxAge] = p;cookieObj[cookieNameMap.MaxAgeDate] = q}};break;case 'domain':{hostName = document.location.hostname.toLowerCase();if (idIPAddress(hostName)) {cookieObj[cookieNameMap.Domain] = hostName;} else {if (value.length > 0) {if (value.charAt(0) != '.') {value = '.' + value};if (isRegExp(hostName, value)) {var p = value.split('.');var q = p.length;if (q == 2 || (q == 3 && p[1] === 'com')) {cookieObj[cookieNameMap.Domain] = '.' + hostName} else {cookieObj[cookieNameMap.Domain] = value}} else {cookieObj[cookieNameMap.Domain] = '.' + hostName}}}};break;case 'path':{if (value.length == 0 || value.charAt(0) !== '/') {cookieObj[cookieNameMap.Path] = getPath();} else {cookieObj[cookieNameMap.Path] = value;}};break;case 'secure':{cookieObj[cookieNameMap.Secure] = true;};break;default:{}break}};function saveCookieOtherPart(cookie, cookieObj) {var name, value = '';var item;var length = cookie.length;for (var index = 0; index < length; index++) {item = cookie[index];var splitObj = item.split('=');name = splitObj[0];if (splitObj.length > 1) {value = splitObj[1];};name = name.trim();if (name.length == 0) {continue};value = value.trim();if (name.toLowerCase() === "httponly") {return false;}else if(name.toLowerCase() === "path"){var isPrefixWithCookiePath = (hasPrefix(getPath(),value) || hasPrefix(document.location.pathname,value));if (!isPrefixWithCookiePath) {return false;}else{parseOthers(name, value, cookieObj);}}else if(name.toLowerCase() === "domain"){if (!(domianMatch(value))) {return false;}else{parseOthers(name, value, cookieObj);}}else{parseOthers(name, value, cookieObj);}};if (typeof cookieObj['domain'] == 'undefined') {cookieObj['domain'] = document.location.hostname.toLowerCase()}return true;};function saveCookieNameAndValue(cookie, cookieObj) {cookie = cookie.trim();if (cookie.length <= 0) {return false};var eq_idx = cookie.indexOf('=');// skip things that don't look like key=valueif (eq_idx < 0) {return false;}var key = cookie.substr(0, eq_idx).trim();var val = cookie.substr(++eq_idx, cookie.length).trim();// quoted valuesif ('"' == val[0]) {val = val.slice(1, -1);}cookieObj[cookieNameMap.Name] = key;cookieObj[cookieNameMap.Value] = val;return true;}function saveCookieStr(cookieStr) {var hostname = document.location.hostname.toLowerCase(),cookie = {name: '',value: '',secure: false,httpOnly: false,path:getPath(),domain:hostname};var cookieSplit = cookieStr.split(';');if (cookieSplit.length > 0) {var name = cookieSplit[0];if (!saveCookieNameAndValue(name, cookie)) {return null;};if (!saveCookieOtherPart(cookieSplit.slice(1, cookieSplit.length), cookie)) {return null;}if (isCookieExpired(cookie)) {updateAllCookie(cookie);} else {updateCookie(cookie);};return cookie;};return null};var getCookieSuc = false;function getCurrentCookie(){var protocol = document.location.protocol,host = document.location.host;if (protocol && host) {try{doCookieSyncRequest(protocol + '//' + host + '/'+requestTK+'/?' + document.location.href);}catch(ex){}}};function doCookieSyncRequest(url) {var xmlHttprequest = new XMLHttpRequest();xmlHttprequest.open('GET', url, false);xmlHttprequest.setRequestHeader('Content-Type', "text/plain");xmlHttprequest.send(null); if (xmlHttprequest.status == 200) {var result = xmlHttprequest.responseText;if ( !result || result.length == 0) {return};try{var cookieJSON = JSON.parse(result);if (typeof cookieJSON === 'object') {getCookieSuc = true;saveCookies(cookieJSON);}}catch(ex){}}    };function saveCookies(cookies) {cookieStore = [];var index = 0, length = cookies.length,item;for ( ; index < length; index ++) {item = cookies[index];if (typeof item[cookieNameMap.ExpiresDate] != 'undefined') {item[cookieNameMap.ExpiresDate] = new Date(item[cookieNameMap.ExpiresDate]);};cookieStore.push(item);}};function updateIfameCookie(message) {var iframes = document.querySelectorAll('iframe');if (!iframes) {return};var length = iframes.length;var index;var iframe;if (length > 0) {for (index = 0; index < length; index++) {iframe = iframes[index];iframe.contentWindow.postMessage(message, '*');}}};function updateCookies(cookies,host){for(var i = 0;i < cookies.length; i++){var item = cookies[i],domain;if (domianMatch(item[cookieNameMap.Domain])) {updateCookie(item);}}}if (top != this) {window.addEventListener('message',function(event) {var data = event['data'];if (((typeof data) === 'object')) {if (typeof data['host'] === 'string' &&  data['nebula_data']) {updateCookies(data['nebula_data'], data['host']);updateIfameCookie(data);if (event.stopImmediatePropagation) {event.stopImmediatePropagation();};return false}}},true)} else {//use this function to update cookiessNebulaUpdateCookies = function(cookies,host,tk) {//native inject token and check this token for forbidden other one call this methodif (ktnebula === tk) {updateCookies(cookies,host);var message = {};message["host"] = host;message["nebula_data"] = cookies;updateIfameCookie(message);}         }};getCurrentCookie();if (getCookieSuc) {Object.defineProperty(document, 'cookie', {get: function() {var cookieStr = getCookieStr();return cookieStr;},set: function(cookieStr) {if (typeof cookieStr !== 'string') {return};saveCookieStr(cookieStr);var message = {};message[msgType] = "cookie";message["cookie"] = cookieStr;message["url"] = document.location.href;message["msgKt"] = ktnebula;//iOS 10 and iOS 11 if call this on unload event,window.webkit can be nullif (webkit && webkit.messageHandlers && webkit.messageHandlers.PSDXMLHTTPREQUESTMESSAGE && webkit.messageHandlers.PSDXMLHTTPREQUESTMESSAGE.postMessage) {safeCallMessage(message);}},configurable: false});}   } }/**********************Util************************/function getAllHTMLFormData(element, fromAjax){var result = [];if (element.nodeName.toLowerCase() == "form") {var serializeResult = NebulaSerialize(element, { hash: true , empty: true });var inputs = [].slice.call(element.querySelectorAll('input'));for(var i = 0; i < inputs.length ; i++){var field = inputs[i];var type = field.type, name = field.name;if(type == 'file' && field.files && field.files.length > 0){var filesLength = field.files.length;for(var j = 0; j < filesLength; j++){//if get file dataif ((element.enctype.toLowerCase() == "application/x-www-form-urlencoded" || element.enctype.toLowerCase() == "text/plain") && !fromAjax) {result.push({"name" : name, "value" : field.files[j].name});}else if (formElemntList[name] && formElemntList[name][j]) {result.push({"name" : name, "value" : formElemntList[name][j]});}else{result.push({"name" : name, "value" : field.files[j]});}}}}for(var key in serializeResult){if (serializeResult.hasOwnProperty(key)) {result.push({"name" : key, "value" : serializeResult[key]});}}}return  result;    }function serializeFormData(data) {return new Promise(function (resolve, reject) {var dataVal = data["value"];if (typeof(dataVal) === "string") {resolve(data);}else if(dataVal instanceof Blob || dataVal instanceof File){var reader = new FileReader();reader.onload = function (event) {var result = event.target.result;if (result.length > 0) {data["value"] = result;resolve(data);}else{reject(new Error(""));}}reader.onerror = function(){reject(new Error(""));}reader.onabort = function(){reject(new Error(""));}reader.readAsDataURL(dataVal);}else{resolve(data);}});}function arrayBufferToBase64(buffer) {var binary = '';var bytes = new Uint8Array(buffer);var len = bytes.byteLength;for (var i = 0; i < len; i++) {binary += String.fromCharCode(bytes[i]);}return window.btoa(binary);}var serializeData = function(data,callback){var reader = new FileReader();reader.onload = function (event) {var result = event.target.result;callback(result);}reader.readAsDataURL(data);}function recordError(error){if (error instanceof Error) {var message = {};message[msgType] = "error";message["errorInfo"] = error.message;message["msgKt"] = ktnebula;safeCallMessage(message);}}function isFormUseGetMethod(element){var item = element;if (item && item.nodeName && (typeof item.nodeName === "string") && item.nodeName.toLowerCase() == "form") {var methodStr = item.method;if (typeof methodStr !== "string") {methodStr = item.getAttribute("method");}if (methodStr && methodStr.toLowerCase() === "get") {return true;}}return false;}function generateFormTargetUrlWithRadom(url,radom){var urlParse = document.createElement('a');urlParse.href = url;var originUrlSearch = urlParse.search ? urlParse.search : "";var originUrlHash = urlParse.hash ? urlParse.hash : "";if (!/X-NEBULAXMLHTTPREQUEST/.test(url)) {if (urlParse.search && urlParse.search.length > 0) {var hrefSearch =  urlParse.search;if (/X-NEBULAXMLHTTPREQUEST/.test(hrefSearch)) {urlParse.search = hrefSearch.replace(/X-NEBULAXMLHTTPREQUEST=(\d+)/,"X-NEBULAXMLHTTPREQUEST="+radom);}else{urlParse.search = hrefSearch + "&X-NEBULAXMLHTTPREQUEST="+radom;}}else{urlParse.search = "?X-NEBULAXMLHTTPREQUEST="+radom;}}else{urlParse.search = urlParse.search.replace(/X-NEBULAXMLHTTPREQUEST=(\d+)/,"X-NEBULAXMLHTTPREQUEST="+radom);}var path = url.replace(originUrlSearch,"").replace(originUrlHash,"");if (path.trim() === '#') {path='';}return {targetUrl:path+urlParse.search+urlParse.hash,fullTargetUrl:urlParse.href};}function addFormExtraInfoWithElement(element){var item = element;if (isFormUseGetMethod(item)) {return;}var radom = (+new Date()) +""+ Math.round((Math.random()*(100000)));//change form element method url for injectvar methodUrl = item.getAttribute("action");if (!methodUrl) {methodUrl = "";}//if has no param add flagvar urlObj = generateFormTargetUrlWithRadom(methodUrl,radom);item.setAttribute("action", urlObj.targetUrl);item.setAttribute("data-fullactionurl", urlObj.fullTargetUrl);item.setAttribute("data-nebulaId",radom);   }/**********************FormData************************/var  FakeFormData = (function(fn){window.originFormData = fn;return function(form){this.realFormData = new fn(form);  if (form) {this.targetForm = form; }this.appendData = [];}})(FormData);FakeFormData.prototype.constructor = window.originFormData;FakeFormData.prototype.append = function(name, value, filename){var filenameInValue = (value!=undefined ? value.name : undefined);this.appendData.push({"name":name,"value":value,"fileName":filename||filenameInValue});//this.realFormData.append(name,value,filename);}FormData = FakeFormData;/**********************Message************************/var messageList = {};var msgId = "msgId",msgCookie = "msgCookie",msgMainUrl = "msgMainUrl",msgRequestUrl = "msgRequestUrl",msgKt = "msgKt",msgVal = "val", msgType = 'type',msgEnctype = 'FormEnctype',msgAcceptCharset = "AcceptCharset",msgErrorMessage = "errorMessage",msgDocumentCharset = "DocumentCharset",msgIsStream = "IsStream";var NEBULAXMLHTTPREQUESTMESSAGEHANDLER = {cacheMessage:function(xmlhttprequest, callFn, args, msgId, kt){if (ktnebula === kt) {messageList[msgId] = {msgId:msgId,callBack:function(){var that = xmlhttprequest;try{return callFn.apply(that, args);}catch(ex){recordError(ex);}}};//if mainProcess message not come back deply 500ms do really callsetTimeout(function(){NEBULAXMLHTTPREQUESTMESSAGEHANDLER.triggerMessageCallBack(msgId, kt);},500);}},triggerMessageCallBack:function(msgId, kt){if (ktnebula === kt) {if (messageList[msgId]){messageList[msgId]["callBack"]();delete  messageList[msgId];}}},addFormExtraInfoToElement:function(target, kt){if (ktnebula === kt) {var message = {};message[msgType] = "FormElement";message[msgKt] = kt;var element = getFormWithElement(target ? target : document.activeElement);//if is get request we should not send message to main processif (isFormUseGetMethod(element)) {return;}if (element) {var dataNebulaId = element.getAttribute("data-nebulaId");var requestUrl = element.getAttribute("data-fullactionurl");var datas = getAllHTMLFormData(element,false);Promise.all(datas.map(function(data){return serializeFormData(data);})).then(function (value) {message[msgId] = dataNebulaId;message[msgVal] = value;message[msgType] = "FormElement";message[msgEnctype] = element.enctype;message[msgAcceptCharset] = element.acceptCharset;message[msgDocumentCharset] = document.charset;message[msgRequestUrl] = requestUrl;safeCallMessage(message);}).catch(function(error){recordError(error);}); return  dataNebulaId;}}},updateCookies:NebulaUpdateCookies}window.NebulaXMLHttpRequestMessageBridge = NEBULAXMLHTTPREQUESTMESSAGEHANDLER;Object.freeze(window.NebulaXMLHttpRequestMessageBridge);Object.defineProperty(window,"NebulaXMLHttpRequestMessageBridge",{configurable:false,writable:false});/**********************XMLHttpRequest************************/// ReWrite send method// https://developer.mozilla.org/zh-CN/docs/Web/API/XMLHttpRequest// void send();// void send(ArrayBuffer data);// void send(Blob data);// void send(Document data);// void send(DOMString? data);// void send(FormData data);//if should stop request injectvar generateTargetHash = function(hash){return "^^^^"+ hash +"^^^^";}var hashRegExp = /\^\^\^\^(\d+)\^\^\^\^/;function generateTargetUrlWithRadom(url,radom){var urlParse = document.createElement('a');urlParse.href = url;var originHash = urlParse.hash ? urlParse.hash : "";if (!hashRegExp.test(urlParse.hash)) {if (urlParse.hash && urlParse.hash.length > 0) {urlParse.hash = urlParse.hash + generateTargetHash(radom);}else{urlParse.hash = generateTargetHash(radom);}}else{urlParse.hash = urlParse.hash.replace(hashRegExp, generateTargetHash(radom));}var urlWithoutHash = url.replace(originHash,"");if (urlWithoutHash.trim() === '#') {urlWithoutHash ='';}return {targetUrl:urlWithoutHash + urlParse.hash,fullTargetUrl:urlParse.href};}var HttpMethods = ['POST', 'PUT', 'PATCH', 'DELETE', 'COPY', 'OPTIONS', 'LINK', 'UNLINK', 'PURGE','TRACE','LOCK', 'UNLOCK', 'VIEW', 'PROPFIND']var isTargetHttpMethod = function(method){if (typeof method == "string") {if (HttpMethods.indexOf(method.toUpperCase()) == -1) {return false;}else{return true;}}return false;}XMLHttpRequest.prototype.open = (function(fn) {return function(method, url, async, username, password) {var args = [].slice.call(arguments);var requestAsync = true;if (args.length > 2) {requestAsync = !!args[2];}this.requestAsync = requestAsync;var radom = (+new Date()) +""+Math.round((Math.random()*(100000)));this.requestId = radom;var fullUrl = "";if (method && isTargetHttpMethod(method)) {var urlObj = generateTargetUrlWithRadom(url,radom);url = urlObj.targetUrl;fullUrl = urlObj.fullTargetUrl;}this.requestUrl = fullUrl;args[1] = url;return fn.apply(this, args);}})(XMLHttpRequest.prototype.open);//XMLHttpRequest rewrite send methodXMLHttpRequest.prototype.send = (function(fn) {return function(e) {var radom = this.requestId;var message = {};var that = this;var args = [].slice.call(arguments);message[msgId] = radom;message[msgKt] = ktnebula;message[msgMainUrl] = document.location.href;message[msgRequestUrl] = this.requestUrl;//if sync requestif (!e) {return fn.apply(this,args);}else if (typeof(e) === 'string' && e.length > 0) {message[msgVal] = e;message[msgType] = "String";safeCallMessage(message);} else if(e instanceof Blob){message[msgType] = "Blob";if (this.requestAsync) {serializeData(e,function(result){message[msgVal] = result;safeCallMessage(message);NEBULAXMLHTTPREQUESTMESSAGEHANDLER.cacheMessage(that,fn,args,radom,ktnebula);});return;}else{message["error"] = "NOTSUPPORT";safeCallMessage(message);}} else if(e instanceof FormData){message[msgType] = "FormData";if (this.requestAsync) {message[msgType] = "FormData";var datas = e.appendData;if (e.targetForm) {datas = datas.concat(getAllHTMLFormData(e.targetForm,true));}Promise.all(datas.map(function(data){return serializeFormData(data);})).then(function (value) {message[msgVal] = value;safeCallMessage(message);NEBULAXMLHTTPREQUESTMESSAGEHANDLER.cacheMessage(that,fn,e.realFormData,radom,ktnebula);}).catch(function(error){recordError(error);})return;}else{message["error"] = "NOTSUPPORT";safeCallMessage(message);}} else if(e.nodeType){message[msgType] = "Document";if (e === document) {message[msgVal] = (new XMLSerializer()).serializeToString(document);}else{message[msgVal] = e.toString();}safeCallMessage(message);} else if(e instanceof ArrayBuffer){//transfor ArrayBuffer to base64message[msgVal] = arrayBufferToBase64(e);message[msgType] = "ArrayBuffer";safeCallMessage(message);} else if(e.buffer){message[msgVal] = arrayBufferToBase64(e.buffer);message[msgType] = "ArrayBuffer";safeCallMessage(message);} else {return fn.apply(this,args);}if (this.requestAsync) {return NEBULAXMLHTTPREQUESTMESSAGEHANDLER.cacheMessage(that,fn,args,radom,ktnebula);}else{return fn.apply(this,args);}}})(XMLHttpRequest.prototype.send);/**********************FormElement************************/var formElemntList = {};window.lastClickElement = null;function getFormWithElement(element){if (element && element.nodeType) {var parentNode = element;while (parentNode) {if (parentNode.nodeName.toLowerCase() === "form") {return parentNode;} else if (parentNode === document || parentNode === document.documentElement || parentNode === document.body) {break;}parentNode = parentNode.parentNode;}return null;}}document.addEventListener("DOMContentLoaded",function(){//inject a hidden input to form element// addFormExtraInfoToElement();//add input file change  and read file datadocument.addEventListener("change",function(e){var targetElement = e.target;if (targetElement.nodeName && targetElement.nodeName.toLowerCase() && targetElement.type && targetElement.type === "file") {var that = targetElement;for(var i = 0; i < that.files.length; i++){(function(fileItem){serializeFormData({name:that.name, value:fileItem}).then(function(value ){//we save files in arrayif (!formElemntList[that.name]) {formElemntList[that.name] = [];}formElemntList[that.name].push({name:that.name,value:value["value"],fileName:fileItem.name});}).catch(function(error){recordError(error);});})(that.files[i])}}},false);document.addEventListener("click",function(e){window.lastClickElement = e.target;},true);},false);//before form form submit to add extraInfodocument.addEventListener("submit",function(e){if (e.target &&  e.target.nodeName && typeof e.target.nodeName === "string" && e.target.nodeName.toLowerCase() == "form") {addFormExtraInfoWithElement(e.target);NEBULAXMLHTTPREQUESTMESSAGEHANDLER.addFormExtraInfoToElement(e.target,ktnebula);}},true);HTMLFormElement.prototype.submit = (function(fn){return function(){//if submit from js method, we send method to main processvar that = this;var args = [].slice.call(arguments);var datas = getAllHTMLFormData(this,false);var message = {};//for dynamic formaddFormExtraInfoWithElement(this);window.lastClickElement = this;NEBULAXMLHTTPREQUESTMESSAGEHANDLER.addFormExtraInfoToElement(this,ktnebula);fn.apply(that,args);}})(HTMLFormElement.prototype.submit);
})();})();

将IMYWebLoader添加到蚂蚁mpaas框架中引发的问题和解决的问题相关推荐

  1. 蚂蚁mPaaS框架控制台打印 原生与h5交互数据 和 RPC接口返回数据 都是Unicode乱码如何处理

    1.原生与h5交互数据 具体的参考之前博客:https://blog.csdn.net/qq_15509071/article/details/113876172 这里修改为: - (void)use ...

  2. laravel 框架中使用数据库迁移添加注释

    laravel 框架中数据库迁移添加注释 在使用laravel框架过程中,估计很多人都有用过数据库迁移文件.可能大家都会在建表时为字段添加注释.我在此要说明的是为表添加注释 首先我们需要引入larav ...

  3. Taro框架中 Image 和 Video 组件预览图片/视频时添加明显的关闭按钮以关闭全屏预览

    需求 Taro框架中 Image 和 Video 组件预览图片/视频时 添加明显的关闭按钮 以关闭全屏观看,避免用户直接操作返回后导致页面空白(原有消息记录消失 - 重新进入项目首页) [补充] 全屏 ...

  4. asp 采集系统_在微服务框架中添加SkyWalking+SkyApm-dotnet分布式链路追踪系统

    1.APM工具的选取 Apm监控工具很多,这里选用网上比较火的一款Skywalking. Skywalking是一个应用性能监控(APM)系统,Skywalking分为服务端Oap.管理界面UI.以及 ...

  5. Unity 之 ToLua框架中UI.Dropdown组件动态添加Options

    前言 最近使用ToLua框架使用Unity中的Dropdown组件,其他属性都还好和在C#中使用的形式差不多,只是修改成了Lua的语法习惯就可以了,但是我有个需求,是要需要实现动态添加Dropdown ...

  6. Ant Design Pro of Vue——蚂蚁金服中后台系统框架搭建

    Ant Design Pro of Vue--蚂蚁金服中后台系统框架搭建 Ant Design Pro of Vue下载安装启动步骤: 一.Ant Design Pro of Vue 的介绍 Ant ...

  7. JFrame(框架)中添加和设置JPanel(面板)的方法

       Swing 程序用JFrame 对象实现了它们的窗口.JFrame 类是AWT Frame 类的一个子类.它还加入了一些Swing 所独有的特性.与 Frame 的使用十分相似.唯一的区别在于, ...

  8. 3 张图带你走近蚂蚁mPaaS音视频通话组件

    简介: 远程问诊.线上开户.车载语音通话--蚂蚁 mPaaS 正在"拥抱新技术,探索新未来". 音视频技术的进步,让线上办公不再是一时权宜之计,也使得线上业务的"无接触& ...

  9. SpringBoot 框架中 使用Spring Aop 、创建注解、创建枚举类 使用过程记录

    1.开始 在Springboot框架中引入AOP <dependency><groupId>org.springframework.boot</groupId>&l ...

最新文章

  1. NPOI 导出Excel
  2. 我练习项目眼中的 vue
  3. 自动开料机器人_工业4.0智能家具无人化生产线 自动化无人化大势所趋
  4. Vista上远程管理Hyper-V服务器
  5. 完整的Web应用程序Tomcat JSF Primefaces JPA Hibernate –第2部分
  6. linux多线程编程——同步与互斥
  7. HDU 5410 CRB and His Birthday ——(完全背包变形)
  8. 遗传算法 优化 工具箱 matlab pareto front,matlab遗传算法三目标优化,出来的pareto前沿图只是二维图...
  9. java判断是否换行_如何检测java中的换行符
  10. Android Studio eclipse 调试技巧
  11. sql loader
  12. 弗兰克赫兹实验matlab画图,物理实验论文
  13. 使用kind快速搭建本地k8s集群
  14. 渗透测试之信息收集总结
  15. 什么是GPU,GPU怎么工作的,什么是图形的渲染,渲染怎么完成的。
  16. Exoplayer2 播放单个音频
  17. nacos界面定制化
  18. MySQL之正则表达式
  19. SolidWorks的通过函数驱动绘制曲线
  20. torch-fidelity 简便计算FID,ISC,KID,PPL

热门文章

  1. 解决谷歌登陆账号失败问题2020-11-21
  2. php GD库做水印功能,合并图片
  3. 串口的使用–蓝牙模块
  4. 最简单的存储过程写法及调用
  5. 图解链表 —— JAVA中的单链表基本操作
  6. 并查集算法(优化) | Union by Rank and Path Compression
  7. 个人博客处理——页面处理
  8. 怎么设置可以将资料横向打印出来
  9. 黑客入门常用的8种工具
  10. VMware 安装Ubuntu系统后,启动一直黑屏