Bing URL Decoder

Decode the Bing URLs to get the direct result page URL

  1. // ==UserScript==
  2. // @name Bing URL Decoder
  3. // @namespace https://github.com/Alistair1231/my-userscripts/
  4. // @version 0.2.8
  5. // @description Decode the Bing URLs to get the direct result page URL
  6. // @author Alistair1231
  7. // @icon https://icons.duckduckgo.com/ip2/bing.com.ico
  8. // @match https://www.bing.com/*
  9. // @license MIT
  10. // ==/UserScript==
  11. // https://greasyfork.org/en/scripts/464094-bing-url-decoder
  12. // https://openuserjs.org/scripts/Alistair1231/Bing_URL_Decoder
  13. (function () {
  14. 'use strict';
  15. // https://stackoverflow.com/a/70429872
  16. function unicodeBase64Decode(text){
  17. text = text.replace(/\s+/g, '').replace(/\-/g, '+').replace(/\_/g, '/');
  18. return decodeURIComponent(Array.prototype.map.call(window.atob(text),function(c){return'%'+('00'+c.charCodeAt(0).toString(16)).slice(-2);}).join(''));
  19. }
  20.  
  21. function decodeBingUrl(url) {
  22. const remove_alink = (x) => {
  23. if (!x.startsWith("https://bing.com/alink/")) {
  24. return x;
  25. }
  26. const urlStartIndex = x.indexOf("url=") + 4;
  27. const urlEndIndex = x.indexOf("&", urlStartIndex);
  28. if (urlEndIndex === -1) {
  29. return x.substring(urlStartIndex);
  30. }
  31. return x.substring(urlStartIndex, urlEndIndex);
  32. };
  33.  
  34. // check if has leading "a1" characters, then Remove the leading "a1" characters from the value of the "u" parameter
  35. var uParamValue;
  36. // check if url.searchParams.get('u') is null and skip
  37. if (url.searchParams.get('u') === null) {
  38. return;
  39. }
  40.  
  41. url.searchParams.get('u').startsWith('a1') ? uParamValue = url.searchParams.get('u').substring(2) : uParamValue = url.searchParams.get('u')
  42.  
  43. // Decode the URL-safe Base64-encoded value
  44. // console.log(url.searchParams.get('u'));
  45. // console.log(unicodeBase64Decode(uParamValue));
  46. var base64DecodedValue = unicodeBase64Decode(uParamValue.replace(/_/g, '/').replace(/-/g, '+'));
  47.  
  48. try {
  49. const decodedValue = decodeURIComponent(base64DecodedValue);
  50. return remove_alink(decodedValue);
  51. } catch (error) {
  52. if (error instanceof URIError) {
  53. return remove_alink(base64DecodedValue);
  54. }
  55. }
  56.  
  57. }
  58.  
  59. function decodeBingUrls(links) {
  60. links.forEach(link => {
  61. // test link.href is not undefined
  62. if (link.href === undefined) {
  63. return;
  64. }
  65.  
  66. const decodedUrl = decodeBingUrl(new URL(link.href));
  67. link.href = decodedUrl;
  68. });
  69. }
  70.  
  71. // Decode all "u" parameters in Bing URLs on the page
  72. const links = document.querySelectorAll('a[href*="bing.com"][href*="&u="]');
  73. decodeBingUrls(links);
  74.  
  75. // Use MutationObserver to detect new links added to the page
  76. const observer = new MutationObserver(mutations => {
  77. mutations.forEach(mutation => {
  78. if (mutation.type === 'childList') {
  79. const newLinks = mutation.addedNodes;
  80. decodeBingUrls(newLinks);
  81. }
  82. });
  83. });
  84.  
  85. var mainContent = null;
  86. // if mainContent is null, wait for 1 second and try again
  87. const loadResults = () => {
  88. mainContent = document.getElementById('b_content');
  89. if (mainContent === null) {
  90. setTimeout(loadResults, 1000);
  91. }
  92. }
  93. observer.observe(mainContent, { childList: true, subtree: true });
  94.  
  95. })();