Solve a scenario and do something unified before and after the request

  • Requests in modern projects tend to be uniformly encapsulated such as doing something in a uniformly contained AXIos method
/ / add a token
axios.interceptors.request.use(
  config= > {
    config.headers['token'] = 'xxxx'
    return config
  },
  error= > {
    return Promise.reject(error)
  }
)
// Unified exception handling
axios.interceptors.response.use(
  response= > {
    const res = response.data
    if(res.code ! = =200) {
      Message({
        message: res.msg || 'Wrong! '.type: 'error'.duration: 5 * 1000.showClose: true
      })
      return Promise.reject(res.msg || 'error')}else {
      return res
    }
  },
  error= > {
    Message({
      message: 'Nothing, just a server error! '.type: 'error'.duration: 5 * 1000.showClose: true
    })
    return Promise.reject(error)
  }
)
Copy the code

Introduce the topic, face the slice

  • AOP simply inserts code dynamically into a specified location of a specified method of a class at run time

  • Benefits: Modules are decoupled, not dependent, reducing redundant code without the need to add functionality to each module.
  • Scenarios: logging, exception handling, and so on
  • Applications include unified front-end request processing, nginx unified request timeout time, unified insertion of specific resources, and back-end log module Log4JS

Break down the scene and return to the theme

  • Today we’re going to be dealing with requests and responses.
  • It is true that unified processing can be addressed under the current schema, but what about scenarios where multiple pages are embedded and different technology stacks are mixed? What about a scenario where we solve specific requests for encryption and decryption in multiple pages?

A bold guess?

  • I am using ajax-hook, such a solution (git address: github.com/wendux/Ajax…
  • How it works: XMLHttpRequest that cannot be modified is modified through attributes such as Object.defineProperty
Object.defineProperty(this, attr, {
    get: getterFactory(attr),
    set: setterFactory(attr),
    enumerable: true
})
Copy the code

* The following is an example

/ * * @ Description: encryption * @ Author: wen-zhou wu * @ making: http://gitlab.yzf.net/wuwenzhou * @ the Date: 2020-03-13 17:39:01 * @Lasteditors: Wu Wenzhou * @LasteditTime: 2020-09-24 17:57:07 */
(function () {
  /** * the url to intercept */
  var urlArray = [' '];
  /** * decrypt data */
  function decryptResultAES(){}/** * returns */ for converting data
  function tryParseJson(v,xhr){
    if (checkUrl(xhr.xhr._ProxyURL)) {
        if (xhr.status === 200 && xhr.readyState === 4) {
            if (xhr.xhr.responseText && JSON.parse(xhr.xhr.responseText).result) {
                var responseText = JSON.parse(xhr.xhr.responseText);
                var result = decryptResultAES(responseText.result);
                if (typeofresponseText.result ! = ='object') {
                    responseText.result = JSON.parse(result);
                    return JSON.stringify(responseText); }}}}else{
      returnv; }}/** * get the url * without suffix@param {*} url* /
  function getUrl(url) {
    return url.indexOf('? ') > 0 ? url.substring(0, url.indexOf('? ')) : url;
  }
  /** * Check whether the array contains the string *@param {*} url* /
  function checkUrl(url) {
    return!!!!! url? urlArray.indexOf(url) >=0:false;
  }
  /** * hijacking request */
  hookAjax({
      responseText: {
        getter: tryParseJson
      },
      response: {
        getter:tryParseJson
      },
      // Intercept the callback
      onreadystatechange: function (xhr) {},onload:function(xhr){},// Intercepting methods
      open: function (arg, xhr) {
        var url = getUrl(arg[1]);
        // Add an identity address by tampering
        Object.defineProperty(xhr, '_ProxyURL', {
          value: url,
          writable: true // Whether can change})},send: function (arg, xhr) {
          if (checkUrl(xhr._ProxyURL)) {
            xhr.setRequestHeader("xxx"."xxx"}}})})()Copy the code
  • Through such js introduction, encryption and decryption can be added to each page without changing any business code.

A sublimation

  • This way still needs to be realized through the introduction of JS pages, although it has been done very well, but can not meet the status quo, further.
  • Nginx can be configured with nginx.org/en/docs/htt…
sub_filter </head> "<script>xxx</script></head>"
Copy the code
  • In this way, there is no need to modify any code to achieve such a function, but the production is careful, setting the business to the operation and maintenance end is not very controllable, but this way is relatively simple

One hundred feet ahead

  • We can do more than that. For example, for the encryption problem just now, both my local development and back-end development submitted the code to the test environment, and the encryption mode was modified. However, many of my friends’ codes were submitted before my current branch time point, and I did not submit the code to the master such a time difference problem.
  • In problem two, the tester found that the interface was encrypted and could not correspond to the page data one by one.
  • If the interface itself is converted into/API /0001, the schematization is very weak.
  • This obviously hampers the testers and prevents them from seeing the debugging once they go live. So there’s this requirement, I want to encrypt when I encrypt, decrypt when I decrypt. Internal personnel are not encrypted state, external customers are encrypted invisible. How can the same browser implement different requests and responses?
  • Think browser is a slice too? The browser is really a slice, implemented through the Google plugin.
  • As long as the insider installed Google plugin, hijacking request is not to achieve the above function.

Google Plugins here I come

  • Project address: github.com/fodelf/easy…
  • The Google plugin enables hijacking requests, including resource and other requests
  • For example, after the request to the matching JS, I modify the resource pointing, is it possible to tamper with the encrypted and decrypted JS to a static resource address of the content server? This JS can completely decrypt the interface address, decryption information to the console output, or I want to modify any resource on the line js, CSS pointing to its own address.
  • Request modification: Similarly, I can modify any attributes of the request, request header information, such as request URL, etc., with the help of the previous ajax-hook library. Application scenarios include tampering with different parameters when crawling some websites, and finding out the corresponding page mapping of different parameters. All request responses are controlled by my plug-in. I want the page to render anything.

Development considerations

  • The Google plugin is added to Google Chrome through resources. Use “build”: “vue-cli-service build –watch” during development, listen for changes and compile in real time, and then refresh resources in Google Extensions Manager.
  • Js about Google plug-in operation function does not need to put in vue SRC, put in the static resource directory, if you need to compile can write scripts.
  • Manifest.json, and the key is the permission configuration item content_scripts which is a way of inserting.
  • Data is shared through storage.
  • Messages are communicated through postMessage.

Resources to address

  • Google Plugin tamper request: github.com/fodelf/easy…
  • Ajax-hook request blocking: github.com/wendux/Ajax…
  • Nginx configuration: nginx.org/en/docs/htt…

conclusion

  • If there is one thing that needs to be done repeatedly in different modules, if we can change a few places now, think again, we can design for slicing, and then we can do whatever the wind is blowing.

The end of the

  • Come on! Working people!