로컬 파일을 열 수 없음-Chrome : 로컬 리소스를로드 할 수 없습니다.


102

테스트 브라우저 : Chrome 버전 : 52.0.2743.116

'C : \ 002.jpg'와 같은 로컬에서 이미지 파일을 여는 간단한 자바 스크립트입니다.

function run(){

   var URL = "file:///C:\002.jpg";

   window.open(URL, null);

}
run();

다음은 내 샘플 코드입니다. https://fiddle.jshell.net/q326vLya/3/

적절한 제안을 해주세요.


<input type=file>지역 자원에 접근하기 위해 사용
dandavis

답변:


64

이것이 오래된 것임을 알고 있지만 이와 같은 많은 질문을보십시오 ...

우리는 교실에서 Chrome을 많이 사용하며 로컬 파일 작업에 필수입니다.

우리가 사용하고있는 것은 "Web Server for Chrome"입니다. 시작하고 작업 할 폴더를 선택하고 URL (예 : 선택한 127.0.0.1:port)로 이동합니다.

간단한 서버이며 PHP를 사용할 수 없지만 간단한 작업을 위해서는 솔루션이 될 수 있습니다.

https://chrome.google.com/webstore/detail/web-server-for-chrome/ofhbbkphhbklhfoeikjpcbhemlocgigb


1
우디 : 정말 고마워요! 이 접근 방식이 도움이되었습니다. Windows 10에서 로컬 Tomcat + 로컬 AWS S3 버킷을 실행합니다. 이제 라이브 AWS 서버와 로컬 서버간에 전환 할 수 있습니다. 건배. Q
user1723453 2010 년

20

좋아요 여러분, 저는이 오류 메시지의 보안 이유를 완전히 이해하고 있지만 때로는 해결 방법이 필요합니다. 이 질문의 기반이 된 JavaScript 대신 ASP.Net을 사용하지만 누군가에게 유용하기를 바랍니다.

사내 앱에는 사용자가 네트워크 전체에 퍼져있는 유용한 파일에 대한 바로 가기 목록을 만들 수있는 웹 페이지가 있습니다. 이 바로 가기 중 하나를 클릭하면이 파일을 열고 싶지만 Chrome의 오류로 인해이를 방지 할 수 있습니다.

여기에 이미지 설명 입력

이 웹 페이지는 AngularJS 1.x를 사용하여 다양한 바로 가기를 나열합니다.

원래 내 웹 페이지는 <a href..>파일을 가리키는 요소 를 직접 만들려고 했지만 Not allowed to load local resource사용자가 이러한 링크 중 하나를 클릭하면 " "오류가 발생했습니다.

<div ng-repeat='sc in listOfShortcuts' id="{{sc.ShtCut_ID}}" class="cssOneShortcutRecord" >
    <div class="cssShortcutIcon">
        <img ng-src="{{ GetIconName(sc.ShtCut_PathFilename); }}">
    </div>
    <div class="cssShortcutName">
        <a ng-href="{{ sc.ShtCut_PathFilename }}" ng-attr-title="{{sc.ShtCut_Tooltip}}" target="_blank" >{{ sc.ShtCut_Name }}</a>
    </div>
</div>

해결책은 해당 <a href..>요소를이 코드 로 대체하여 Angular 컨트롤러에서 함수를 호출하는 것입니다.

<div ng-click="OpenAnExternalFile(sc.ShtCut_PathFilename);" >
    {{ sc.ShtCut_Name }}
</div>

기능 자체는 매우 간단합니다 ...

$scope.OpenAnExternalFile = function (filename) {
    //
    //  Open an external file (i.e. a file which ISN'T in our IIS folder)
    //  To do this, we get an ASP.Net Handler to manually load the file, 
    //  then return it's contents in a Response.
    //
    var URL = '/Handlers/DownloadExternalFile.ashx?filename=' + encodeURIComponent(filename);
    window.open(URL);
}

그리고 내 ASP.Net 프로젝트에서 DownloadExternalFile.aspx다음 코드가 포함 된 Handler 파일을 추가했습니다 .

namespace MikesProject.Handlers
{
    /// <summary>
    /// Summary description for DownloadExternalFile
    /// </summary>
    public class DownloadExternalFile : IHttpHandler
    {
        //  We can't directly open a network file using Javascript, eg
        //      window.open("\\SomeNetworkPath\ExcelFile\MikesExcelFile.xls");
        //
        //  Instead, we need to get Javascript to call this groovy helper class which loads such a file, then sends it to the stream.  
        //      window.open("/Handlers/DownloadExternalFile.ashx?filename=//SomeNetworkPath/ExcelFile/MikesExcelFile.xls");
        //
        public void ProcessRequest(HttpContext context)
        {
            string pathAndFilename = context.Request["filename"];               //  eg  "\\SomeNetworkPath\ExcelFile\MikesExcelFile.xls"
            string filename = System.IO.Path.GetFileName(pathAndFilename);      //  eg  "MikesExcelFile.xls"

            context.Response.ClearContent();

            WebClient webClient = new WebClient();
            using (Stream stream = webClient.OpenRead(pathAndFilename))
            {
                // Process image...
                byte[] data1 = new byte[stream.Length];
                stream.Read(data1, 0, data1.Length);

                context.Response.AddHeader("Content-Disposition", string.Format("attachment; filename={0}", filename));
                context.Response.BinaryWrite(data1);

                context.Response.Flush();
                context.Response.SuppressContent = true;
                context.ApplicationInstance.CompleteRequest();
            }
        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }

그리고 그게 다야.

이제 사용자가 내 바로 가기 링크 중 하나를 클릭하면 OpenAnExternalFile함수를 호출 하여이 .ashx 파일을 열고 열고 자하는 파일의 경로 + 파일 이름을 전달합니다.

이 핸들러 코드는 파일을로드 한 다음 HTTP 응답에 해당 콘텐츠를 다시 전달합니다.

그리고 작업이 완료되면 웹 페이지에서 외부 파일을 엽니 다.

휴! 다시 말하지만, 크롬이이 " Not allowed to load local resources"예외를 던지는 이유가 있습니다. 따라서 이것에 주의를 기울이십시오 ...하지만이 코드가이 제한을 극복하는 매우 간단한 방법임을 보여주기 위해이 코드를 게시하고 있습니다.

마지막 코멘트 : 원래 질문은 " C:\002.jpg" 파일을 열고 싶었습니다 . 당신 이것을 할 수 없습니다 . 웹 사이트는 하나의 서버 (자체 C : 드라이브 포함)에 위치하며 사용자의 C : 드라이브에 직접 액세스 할 수 없습니다. 따라서 최선의 방법은 네트워크 드라이브의 어딘가에있는 파일에 액세스하기 위해 내 것과 같은 코드를 사용하는 것입니다.


좋은 것 같지만 인증 (읽기 권한)을 어떻게 처리합니까? 모든 사용자가 주어진 파일을 볼 수없는 경우 어떻게합니까? 요청하는 사용자의 이름으로 읽기를 수행 할 필요가 없습니까?
Timi

웹 클라이언트를 사용하여 로컬 파일을 여는 이유는 무엇입니까? 그리고 나를 위해 C : \ SomeNetworkPath \ ...를 열려고합니다.
Kev

각도를 사용하지 않는 경우에도 가능합니까?
Ahmad.Tr

이것은 유용한 대답 이었지만이 ashx 핸들을 통해 이와 같이 렌더링되고 다운로드되는 수백 장의 사진이있는 경우 웹 페이지의로드 시간에 큰 영향을 미칩니다.
Jamshaid Kamran

17

Chrome은 특히 보안상의 이유로 이러한 방식으로 로컬 파일 액세스를 차단합니다.

다음은 Chrome에서 플래그를 활성화하는 해결 방법입니다 (그리고 시스템을 취약성까지 개방).

c : \ Program Files (x86) \ google \ chrome \ Application \ chrome.exe --allow-file-access-from-files


4
"c : \ path \ chrome.exe"-allow-file-access-from-files 솔루션을 따르려고했지만 열 수 없습니다. 이 웹 사이트 fiddle.jshell.net/q326vLya/3을 테스트하십시오 . 내가 뭘 잘못하고 있죠?
KBH

6
GoogleChrome 66에서는 작동하지 않습니다. Chrome은 해당 플래그로 시작하지만 여전히 로컬 파일을 열 수 있음을 보여줍니다.
라돈 8472

16

1) 터미널을 열고 입력하십시오

npm install -g http-server

2) 파일을 제공하려는 루트 폴더로 이동하여 다음을 입력하십시오.

http-server ./

3) 터미널의 출력을 읽으면 뭔가 http://localhost:8080가 나타납니다.

거기에있는 모든 것을 얻을 수 있습니다. 예:

background: url('http://localhost:8080/waw.png');


HTTP 서버는 이제 오류를 일으키는 문제가 있습니다 - 당신은 수정에 불구하고 0.9로 다운 그레이드 할 수 있습니다 - 볼 stackoverflow.com/questions/56364464/...
브라이언 화상

이것은 나에게 가장 간단한 대답이었습니다. 100 % 일했습니다. 감사!
robrecord

9

Chrome 용 웹 서버를 사용하는 해결 방법이 있습니다 .
단계는 다음과 같습니다.

  1. 크롬에 확장을 추가합니다.
  2. 폴더 (C : \ images)를 선택하고 원하는 포트에서 서버를 시작합니다.

이제 로컬 파일에 쉽게 액세스 할 수 있습니다.

function run(){
   // 8887 is the port number you have launched your serve
   var URL = "http://127.0.0.1:8887/002.jpg";

   window.open(URL, null);

}
run();

추신 : 원본 간 액세스 오류가 발생할 경우 고급 설정에서 CORS 헤더 옵션을 선택해야 할 수 있습니다.


6

프로젝트 디렉터리 외부 또는 사용자 수준 디렉터리에서 이미지를로드 할 수 없으므로 "로컬 리소스에 액세스 할 수 없음 경고"가 표시됩니다.

그러나에서 {rootFolder}\Content\my-image.jpg와 같이 프로젝트의 루트 폴더에 파일을 배치하고 다음과 같이 참조하는 경우 :

<img src="/Content/my-image.jpg" />

5

이 문제는 PHP를 서버 측 언어로 사용할 때 발생하며 해결 방법은 결과를 클라이언트에 보내기 전에 내 이미지의 base64 인코딩을 생성하는 것이 었습니다.

$path = 'E:/pat/rwanda.png';
$type = pathinfo($path, PATHINFO_EXTENSION);
$data = file_get_contents($path);
$base64 = 'data:image/' . $type . ';base64,' . base64_encode($data);

나는 누군가에게 자신의 작업을 만들 아이디어를 줄 수 있다고 생각합니다.

감사


2

Google 크롬은 보안상의 이유로 로컬 리소스를로드 할 수 없습니다. Chrome에는 http URL이 필요합니다. Internet Explorer 및 Edge는 로컬 리소스를로드 할 수 있지만 Safari, Chrome 및 Firefox는 로컬 리소스를로드 할 수 없습니다.

파일 위치로 이동하여 거기에서 Python 서버를 시작하십시오.

python -m SimpleHttpServer

그런 다음 해당 URL을 함수에 넣으십시오.

function run(){
var URL = "http://172.271.1.20:8000/" /* http://0.0.0.0:8000/ or http://127.0.0.1:8000/; */
window.open(URL, null);
}

2

PHP가 설치되어 있으면 내장 서버를 사용할 수 있습니다. 파일로 대상 디렉토리를 열고 실행하십시오.

php -S localhost:8001

1

이렇게 할 수 있다면 파일 시스템에 액세스 할 수 있고 잠재적으로 거기에서 사용 가능한 데이터에 대해 조치를 취할 수 있으므로 큰 보안 문제가 될 것입니다. 다행히도 수행하려는 작업을 수행 할 수 없습니다.

액세스 할 로컬 리소스가 필요한 경우 컴퓨터에서 웹 서버를 시작할 수 있으며이 경우 방법이 작동합니다. Chrome 설정에서 작동하는 것과 같은 다른 해결 방법도 가능하지만, 저는 항상 깨끗한 방법을 선호합니다. 로컬 웹 서버를 다른 포트에 설치하는 것입니다 (아니, 그렇게 어렵지 않습니다!).

또한보십시오:


규칙의 이유는 기술적 인 것보다 더 사회적입니다. 브라우저는 이미 오프 도메인 리소스 (예 : SOP, CDN 스크립트, 딥 링크 된 IMG 태그 등)에 대한 프로그래밍 방식의 액세스를 방지하는 좋은 작업을 수행하지만 , 브라우저 창에서 로컬 콘텐츠 를 보는 사람들을 놀라게 합니다. 스크립트는 그것이 보여주는 것을 말할 수 없습니다 ...
dandavis

1
@dandavis 예, 맞아요. 그래도 이런 일이 일어나지 않도록하는 것이 좋을 수 있다고 믿습니다. 일부 구현의 버그 외에도 (로컬 리소스를 열 수없는 경우 더 안전 할 수 있음) 다른 사람들이 화면을 보는 특정 시나리오 (화면 공유 앱 또는 단순히 사무실에서 등 뒤에서)가있을 수 있습니다. ) 로컬 파일 시스템의 위치를 ​​추측 할 수있는 일부 웹 사이트를 방문하는 것만으로 이미지 (신용 카드 또는 개인 이미지)를 열 수있는 것을
원하지 않습니다

1

모든 이미지 네트워크 경로를 저장된 인코딩 된 HTML 문자열의 바이트 문자열로 바꾸면됩니다. 이를 위해 Html 문자열을 Html 문서로 변환하려면 HtmlAgilityPack이 필요했습니다. https://www.nuget.org/packages/HtmlAgilityPack

아래 코드를 찾아 각 이미지 src 네트워크 경로 (또는 로컬 경로)를 바이트 스팅으로 변환합니다. IE, 크롬 및 파이어 폭스에서 네트워크 경로 (또는 로컬 경로)가있는 모든 이미지를 확실히 표시합니다.

string encodedHtmlString = Emailmodel.DtEmailFields.Rows[0]["Body"].ToString();

// Decode the encoded string.
StringWriter myWriter = new StringWriter();
HttpUtility.HtmlDecode(encodedHtmlString, myWriter);
string DecodedHtmlString = myWriter.ToString();

//find and replace each img src with byte string
HtmlDocument document = new HtmlDocument();
document.LoadHtml(DecodedHtmlString);
document.DocumentNode.Descendants("img")
    .Where(e =>
    {
        string src = e.GetAttributeValue("src", null) ?? "";
        return !string.IsNullOrEmpty(src);//&& src.StartsWith("data:image");
    })
    .ToList()
    .ForEach(x =>
        {
        string currentSrcValue = x.GetAttributeValue("src", null);                                
        string filePath = Path.GetDirectoryName(currentSrcValue) + "\\";
        string filename = Path.GetFileName(currentSrcValue);
        string contenttype = "image/" + Path.GetExtension(filename).Replace(".", "");
        FileStream fs = new FileStream(filePath + filename, FileMode.Open, FileAccess.Read);
        BinaryReader br = new BinaryReader(fs);
        Byte[] bytes = br.ReadBytes((Int32)fs.Length);
        br.Close();
        fs.Close();
        x.SetAttributeValue("src", "data:" + contenttype + ";base64," + Convert.ToBase64String(bytes));                                
    });

string result = document.DocumentNode.OuterHtml;
//Encode HTML string
string myEncodedString = HttpUtility.HtmlEncode(result);

Emailmodel.DtEmailFields.Rows[0]["Body"] = myEncodedString;

1

Chrome 및 기타 브라우저는 보안상의 이유로 서버 액세스를 로컬 파일로 제한합니다. 그러나 허용 된 액세스 모드에서 브라우저를 열 수 있습니다. 터미널을 열고 chrome.exe가 저장된 폴더로 이동하여 다음 명령을 작성하십시오.

chrome.exe --allow-file-access-from-files

자세한 내용은 이것을 읽으십시오

이 방법은 나에게 적합하지 않았으므로 특정 디렉토리의 모든 파일에 대해 다른 경로를 만들었습니다. 따라서 해당 경로로 이동하는 것은 해당 파일을 여는 것을 의미합니다.

function getroutes(list){ 
    list.forEach(function(element) { 
        app.get("/"+ element, function(req, res) { 
            res.sendFile(__dirname + "/public/extracted/" + element); 
       }); 
   }); 
}

이 함수를 호출하여 디렉토리의 파일 이름 목록을 전달하고 __dirname/public/extracted서버 측에서 렌더링 할 수있는 각 파일 이름에 대해 다른 경로를 생성했습니다.


0

이 솔루션은 PHP에서 저에게 효과적이었습니다. 브라우저에서 PDF를 엽니 다.

// $path is the path to the pdf file
public function showPDF($path) {
    if($path) {
        header("Content-type: application/pdf");
        header("Content-Disposition: inline; filename=filename.pdf");
        @readfile($path);
    }
}

0

이 문제가 발생했으며 Angular에 대한 솔루션이 있습니다 .Angular의 자산 폴더를 encodeURIComponent () 함수로 래핑했습니다. 효과가있었습니다. 그러나 여전히 다음이있는 경우이 솔루션의 위험에 대해 더 알고 싶습니다.

```const URL = ${encodeURIComponent(/assets/office/file_2.pdf )} window.open (URL)

I used Angular 9, so this is my url when I clicked open local file:
```http://localhost:4200/%2Fassets%2Foffice%2Ffile_2.pdf```
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.