@@ -939,10 +939,35 @@ class HtmlWebpackPlugin {
939939 * Encode each path component using `encodeURIComponent` as files can contain characters
940940 * which needs special encoding in URLs like `+ `.
941941 *
942+ * Valid filesystem characters which need to be encoded for urls:
943+ *
944+ * # pound, % percent, & ampersand, { left curly bracket, } right curly bracket,
945+ * \ back slash, < left angle bracket, > right angle bracket, * asterisk, ? question mark,
946+ * blank spaces, $ dollar sign, ! exclamation point, ' single quotes, " double quotes,
947+ * : colon, @ at sign, + plus sign, ` backtick, | pipe, = equal sign
948+ *
949+ * However the query string must not be encoded:
950+ *
951+ * fo:demonstration-path/very fancy+name.js?path=/home?value=abc&value=def#zzz
952+ * ^ ^ ^ ^ ^ ^ ^ ^^ ^ ^ ^ ^ ^
953+ * | | | | | | | || | | | | |
954+ * encoded | | encoded | | || | | | | |
955+ * ignored ignored ignored ignored ignored
956+ *
942957 * @param {string } filePath
943958 */
944959 urlencodePath ( filePath ) {
945- return filePath . split ( '/' ) . map ( encodeURIComponent ) . join ( '/' ) ;
960+ // People use the filepath in quite unexpected ways.
961+ // Try to extract the first querystring of the url:
962+ //
963+ // some+path/demo.html?value=abc?def
964+ //
965+ const queryStringStart = filePath . indexOf ( '?' ) ;
966+ const urlPath = queryStringStart === - 1 ? filePath : filePath . substr ( 0 , queryStringStart ) ;
967+ const queryString = filePath . substr ( urlPath . length ) ;
968+ // Encode all parts except '/' which are not part of the querystring:
969+ const encodedUrlPath = urlPath . split ( '/' ) . map ( encodeURIComponent ) . join ( '/' ) ;
970+ return encodedUrlPath + queryString ;
946971 }
947972
948973 /**
0 commit comments