복제에 대해서 얘기를 나눠보도록 하겠습니다.붙이다

32964 단어
JS 응용 프로그램을 구축할 때 복사와 붙여넣기를 안전하게 처리하는 것보다 더 복잡한 문제는 없다.이렇게 간단한 조작.오프라인으로 1페이지/탭/문서에 참여하여 선택한 내용을 강조 표시하고, 복사하고, 응용 프로그램의 탭을 열고, 커서를 편집 가능 영역으로 이동하고, 붙여넣습니다.무의식적으로 보이지만 이런 간단한 조작이 큰 스트레스를 주는 원인이다.
걱정해야 할 사항:
  • XSS: Javascript
  • 을 붙여넣지 않아야 합니다.
  • 손상된 HTML: 수정해야 합니다. 그렇지 않으면 브라우저가
  • 으로 간주하는 방식을 "수정"해야 합니다.
  • 속성 혼란: 많은 응용 프로그램들이 여전히 끝없는 style="" 블록, data-my-weird-thing-in-this-app 속성과 클래스를 가져올 수 있다. 이것은 응용 프로그램
  • 과 충돌할 수 있다.
  • 단어 지옥: 오, 무서운 단어의 속성과 무효한 실체가 사방으로 날아다닌다.물론 Office365는 네트워크를 근본으로 하여 더욱 좋아질 수 있지만, 그것들은 여전히
  • 에 존재한다
  • 빈 물건: 불필요한div,span,section,p,b 따위는 당신의 이전 원시dom를 엉망으로 만들 수 있습니다
  • HAXTheWeb은 인터넷에서 가장 좋은 창작과 창작 체험이 되고 플랫폼과 무관한 방식으로 개발자가 새로운 웹 구성 요소를 간단하게 제작하여 콘텐츠 작가에게 새로운 자산을 창출할 수 있기를 희망한다.

    복사/붙여넣기 처리 방법
    많은 솔루션이 있고 심지어 우리 솔루션에도 많지만 우리는 utils 환매 협의를 만들었습니다. 당신은 우리의 해결 방안을 가져올 수 있고 그 중에서 많은 부분을 얻을 수 있습니다.네, 이것은 우리의 위생 방법이기 때문에 아마도 당신들의 방법이 다를 것입니다.
    @lrnwebcomponents/utils
    yarn add @lrnwebcomponents/utils
    npm install @lrnwebcomponents/utils
    
    당신은 우리 모노포에서 see the exact code of this package을 사용할 수 있습니다.지금 나는 하나하나 설명하고 그것이 무엇을 하고 있는지 설명할 것이다.후속 글은 클립보드를 사용하여 이 기능을 실현하는 실제 이벤트 리스트 논리를 소개할 것이다.

    비밀번호 보여주세요.
    저는 다음 글에서 실현을 논의할 것입니다. 그러나 간략화를 위해 here's how we're getting the paste data:
    if (e.clipboardData || e.originalEvent.clipboardData) {
            pasteContent = (e.originalEvent || e).clipboardData.getData(
              "text/html"
            );
          } else if (window.clipboardData) {
            pasteContent = window.clipboardData.getData("Text");
          }
    
    이것은 풍부한 HTML이거나 내용을 복사한 텍스트 내용만 가져오는 브라우저 간의 붙여넣기 데이터를 확보할 수 있습니다.풍부한 텍스트는 다른 프로그램에서 HTML 속성을 제공하지만, 가장 골치 아픈 문제를 정리할 수 있습니다.

    단계 1: 줄 바꿈/Mso 클래스 제거
    function stripMSWord(input) {
      // 1.  remove line breaks / Mso classes right off the bat
      var output = input
        .split("\n\r")
        .join("\n")
        .split("\r")
        .join("\n")
        .split("\n\n")
        .join("\n")
        .split("\n\n")
        .join("\n")
        .split("\n\n")
        .join("\n")
        .split("\n")
        .join(" ")
        .replace(/( class=(")?Mso[a-zA-Z]+(")?)/g, "");
    
    이 일련의 이상한 split/join 문장은 우리가 터무니없이 높은 내용 블록을 가져오지 않도록 보장한다.\r은 귀환, \n은 끝줄.모든 가능한 조합을 확보하기 위해서 (브라우저/응용 프로그램/운영체제에서), 우리는 쌍선으로 끝을 맺고, 이 선을 기반으로 하는 그룹으로 변환한 다음, 단일선으로 그룹을 문자열로 다시 연결합니다.
    이것은 이상하게 보일 수도 있지만, 대량의 공백을 남길 수 있는 프로그램들이 원격으로 읽을 수 있는 내용을 보내는 동안 공백이 없을 것을 확보했다.나중에 우리는 정규 표현식으로 재료를 바꾸었는데, 이것도 그 중 일부를 간소화시켰다.
    마지막으로, 우리는 Mso류를 찾아 파괴했고, 마이크로소프트는 그것을 모든 곳에 두었다.나중에 우리는 모든 수업을 죽였지만, 나는 사람들이 사무실에 목표만 맞추려고 하지 않도록 이것을 여기에 남겨 둘 것이라고 생각한다.

    2단계: HTML 주석 삭제
      // 2. strip Word generated HTML comments
      output = output.replace(/<\!--(\s|.)*?-->/gim, "");
      output = output.replace(/<\!(\s|.)*?>/gim, "");
    
    이상하게 보이는 이 정규 표현식은 HTML 출력의 모든 주석을 대상으로 완전히 삭제합니다.어떤 프로그램들은 그것들을 넣고, 나는 개인적으로 그것들이 평론을 보낼 필요가 없다.
      // 3. remove tags leave content if any
      output = output.replace(
        /<(\/)*(meta|link|html|head|body|span|font|br|\\\\?xml:|xml|st1:|o:|w:|m:|v:)(\s|.)*?>/gim,
        ""
      );
    
    또 하나 이상한 거.이것은 몇 가지 문제를 해결하기 위해서입니다. 당신은 <p>The problem is <font>some actual content</font> can be found in there too.</p>과 비슷한 메일을 받을 것입니다.이 경기는 머리, 몸, 경계, 글씨체, Br 등 라벨의 내용을 채택하고 라벨 포장을 죽여 내부 내용을 남길 것이다.우리의 예에서 정규 표현식을 운행한 결과 우리는 <p>The problem is some actual content can be found in there too.</p>을 얻었다
      // 4. Remove everything in between and including tags '<style(.)style(.)>'
      var badTags = ["style", "script", "applet", "embed", "noframes", "noscript"];
      for (var i in badTags) {
        let tagStripper = new RegExp(
          "<" + badTags[i] + "(s|.)*?" + badTags[i] + "(.*?)>",
          "gim"
        );
        output = output.replace(tagStripper, "");
      }
    
    이것은 우리 XSS 전략의 일부분이다.만약 스타일, 자바스크립트, 혹은 applet/embed 같은 오래된 탭을 붙여 넣으려고 시도한다면, 우리는 바꾸지 않고 그것들을 완전히 죽일 것입니다.모든 일이 다 지나갔다.
      // 5. remove attributes ' style="..."', align, start
      output = output.replace(/ style='(\s|.)*?'/gim, "");
      output = output.replace(/ face="(\s|.)*?"/gim, "");
      output = output.replace(/ align=.*? /g, "");
      output = output.replace(/ start='.*?'/g, "");
      // ID's wont apply meaningfully on a paste
      output = output.replace(/ id="(\s|.)*?"/gim, "");
      // Google Docs ones
      output = output.replace(/ dir="(\s|.)*?"/gim, "");
      output = output.replace(/ role="(\s|.)*?"/gim, "");
    
    이것은 매우 공격적이지만, 나는 스타일, 얼굴 (허구의 단어), 정렬 (단어), 시작 (단어), id (접근성/스타일 각도에서 붙일 수 있는 내용과 충돌할 수 있음),dir (구글이 필요 없는 dir="ltr"), 역할 (마찬가지로 그 안에 붙인 로컬 프로그램이 이 점을 책임진다) 을 원하지 않는다.
      // 6. some HAX specific things in case this was moving content around
      // these are universally true tho so fine to have here
      output = output.replace(/ contenteditable="(\s|.)*?"/gim, "");
      // some medium, box, github and other paste stuff as well as general paste clean up for classes
      // in multiple html primatives
      output = output.replace(/ data-(\s|.)*?"(\s|.)*?"/gim, "");
      output = output.replace(/ class="(\s|.)*?"/gim, "");
    
    우리는 HAX의 상하문에서 그것을 사용하기 때문에 여기에 약간의 추가 내용을 추가했다.이것들은 대다수 사람들에게 유용해야 하지만, 분명히 보기 위해서 나는 그것들을 차단했다.이것은contenteditable, 일치하는 data-{WHATEVER}과 모든 class의 내용을 지울 것입니다.마지막으로 당신의 거래를 망칠 수도 있지만, 저는 미디어(예를 들어)를 필요로 하지 않습니다. <p class="as er df sd fg ds we ds cx sd yt fg as xc sd qf ds qw">Thing</p>을 제 모든 스티커 내용에 무제한으로 추가할 필요가 없습니다. (예, 그들의 종류는 이렇습니다.)
      // 7. clean out empty paragraphs and endlines that cause weird spacing
      output = output.replace(/&nbsp;/gm, " ");
      // start of double, do it twice for nesting
      output = output.replace(/<section>/gm, "<p>");
      output = output.replace(/<\/section>/gm, "</p>");
      output = output.replace(/<p><p>/gm, "<p>");
      output = output.replace(/<p><p>/gm, "<p>");
      // double, do it twice for nesting
      output = output.replace(/<\/p><\/p>/gm, "</p>");
      output = output.replace(/<\/p><\/p>/gm, "</p>");
      // normalize BR's; common from GoogleDocs
      output = output.replace(/<br \/>/gm, "<br/>");
      output = output.replace(/<p><br \/><b>/gm, "<p><b>");
      output = output.replace(/<\/p><br \/><\/b>/gm, "</p></b>");
      // some other things we know not to allow to wrap
      output = output.replace(/<b><p>/gm, "<p>");
      output = output.replace(/<\/p><\/b>/gm, "</p>");
      // drop list wrappers
      output = output.replace(/<li><p>/gm, "<li>");
      output = output.replace(/<\/p><\/li>/gm, "</li>");
      // bold wraps as an outer tag like p can, and on lists
      output = output.replace(/<b><ul>/gm, "<ul>");
      output = output.replace(/<\/ul><\/b>/gm, "</ul>");
      output = output.replace(/<b><ol>/gm, "<ol>");
      output = output.replace(/<\/ol><\/b>/gm, "</ol>");
      // try ax'ing extra spans
      output = output.replace(/<span><p>/gm, "<p>");
      output = output.replace(/<\/p><\/span>/gm, "</p>");
      // empty with lots of space
      output = output.replace(/<p>(\s*)<\/p>/gm, " ");
      // empty p / more or less empty
      output = output.replace(/<p><\/p>/gm, "");
      output = output.replace(/<p>&nbsp;<\/p>/gm, " ");
      // br somehow getting through here
      output = output.replace(/<p><br\/><\/p>/gm, "");
      output = output.replace(/<p><br><\/p>/gm, "");
      // whitespace in reverse of the top case now that we've cleaned it up
      output = output.replace(/<\/p>(\s*)<p>/gm, "</p><p>");
    
    이것은 내가 구글과 다른 몇몇 사이트에서 붙일 때 발견한 일련의 이상한 불일치점이다.복제된 모든 컨텐트를 <p><p></p></p> 태그(<b>의 사용되지 않는 버전)로 포장하는 <strong> 이상의 애플리케이션이 생성되고 있습니다.
    이 블록은 무작위 경계를 정리했다.ol은 b에서,ul은 b에서,p는 li에서,p는 p에서,b는 p에서,p는p에서,p는span에서,그리고 거의 무의미한 것들,예를 들어 한 줄의 여러 공중에서 끊어진 것들.이것은 순수한 HTML 구조를 보여주고 정규 표현식을 통해 수정하는 동시에 바로잡기 위한 매우 적극적인 시도이다.
      // wow do I hate contenteditable and the dom....
      // bold and italic are treated as if they are block elements in a paste scenario
      // 8. check for empty bad tags
      for (var i in badTags) {
        let emptyTagRemove = new RegExp(
          "<" + badTags[i] + "></" + badTags[i] + ">",
          "gi"
        );
        output = output.replace(emptyTagRemove, "");
      }
      output = output.trim();
      return output;
    }
    
    마지막으로, 나는 빈 탭을 지우기 위해 마지막 검사를 했다. (위에 있어야 하는데, 단지 검사를 했을 뿐이다.) 그리고 나는 편집을 했다. (문자열 양쪽에서 공백을 제거했다.)
    이렇게 해서 우리는 이미 내용을 정리했다.나는 최근에 HAX가 붙여넣기 작업을 처리하는 방식을 개선했는데, 그 중 일부 작업은 이 스크립트를 둘러싸고 진행되었다.항상 개선할 여지가 있다. 우리의 일부 필터는 매우 급진적이기 때문에, 일부 부분을 나누어 사용하거나 복사해서 사용하려고 할 수도 있다.
    이 코드를 더 빨리 사용하거나 적게 사용하는 방법에 대한 조언이 있다면 반갑습니다.나는 그것이 의존을 받지 않기를 바란다. (그래, 나는 많은 정화기가 있다는 것을 안다.)
    다음 글에서는 붙여넣은 데이터를 HAX에서 어떻게 처리하는지 논리를 설명할 것이다.HAX는 많은 장애를 뛰어넘어 붙인 내용이 논리적이고 블록 형식이며 잘 쓰여져 있고 임의의 추가 속성/간격이 없음을 확보하려고 시도했다(분명히 안전했다!).
    이 점은 HAX에서 매우 흔히 볼 수 있지만, 만약 누군가가 자신의 보고 얻은 편집기를 만들고 싶다면, 나는 그것을 쓸 것이다.

    좋은 웹페이지 즐겨찾기