Sencha 서버 없이 local 디렉토리에서 CORS 에러 발생했을 때

2025. 1. 26. 18:36Javascript/Sencha

index.html

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link rel="stylesheet" type="text/css" href="theme-classic-all.css">
<script type="text/javascript" src="ext-all.js"></script>
<script type="text/javascript" src="packages/charts/classic/charts.js"></script>
<script type="text/javascript" src="Test.js"></script>

Test.js

Ext.onReady(function () {
	// Create the grid
    var drawContainer = Ext.create('Home.view.file.DragDropGrid', {
        renderTo: Ext.getBody(),
        width: 500,
        height: 800,
    });

DragDropGrid.js

    Ext.define('Home.view.file.DragDropGrid', {
        extend: 'Ext.panel.Panel',
        xtype: 'dragdropgrid',
        title: 'Drag and Drop File Upload',
        layout: 'fit',
        items: [
            {
                xtype: 'grid',
                itemId: 'fileGrid',
                store: {
                    fields: ['name', 'size', 'type'],
                    data: []
                },
                columns: [
                    { text: 'File Name', dataIndex: 'name', flex: 1, align: 'center' },
                    { text: 'Size (KB)', dataIndex: 'size', align: 'center', renderer: value => (value / 1024).toFixed(2) },
                    { text: 'Type', dataIndex: 'type', flex: 1, align: 'center' }
                ],
                viewConfig: {
                    plugins: {
                        ptype: 'gridviewdragdrop',
                        ddGroup: 'fileDDGroup',
                    },
                    listeners: {
                        drop: function(node, data, dropRec, dropPosition) {
                            Ext.Msg.alert('Dropped', 'Files dropped into the grid.');
                        }
                    }
                }
            }
        ],
        listeners: {
            afterrender: function() {
                const panel = this;
                const grid = panel.down('#fileGrid');
                const view = grid.getView();

                // Configure drag-and-drop zone
                const dropZone = new Ext.dd.DropZone(view.el, {
                    getTargetFromEvent: function(e) {
                        return view.getEl();
                    },
                    onNodeEnter: function(target, dd, e, data) {
                        Ext.get(target).addCls('grid-drop-target');
                    },
                    onNodeOut: function(target, dd, e, data) {
                        Ext.get(target).removeCls('grid-drop-target');
                    },
                    onNodeOver: function(target, dd, e, data) {
                        return Ext.dd.DropZone.prototype.dropAllowed;
                    },
                    onNodeDrop: function(target, dd, e, data) {
                        const files = e.browserEvent.dataTransfer.files;
                        if (files) {
                            const fileStore = grid.getStore();
                            for (let i = 0; i < files.length; i++) {
                                const file = files[i];
                                fileStore.add({
                                    name: file.name,
                                    size: file.size,
                                    type: file.type || 'Unknown'
                                });
                            }
                            return true;
                        }
                        return false;
                    }
                });

                panel.on('destroy', function() {
                    dropZone.unreg();
                });
            }
        }
    });

Error

ext-all.js:1 Access to XMLHttpRequest at 'file:///D:/{디렉토리}/Home/view/file/DragDropGrid.js' from origin 'null' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: chrome, chrome-extension, chrome-untrusted, data, http, https, isolated-app.

보정: Test.js에 define 내용까지 포함해 버림

Test.js

Ext.onReady(function () {
    // Add DragDropGrid definition directly here
    Ext.define('Home.view.file.DragDropGrid', {
        extend: 'Ext.panel.Panel',
        xtype: 'dragdropgrid',
        title: 'Drag and Drop File Upload',
        layout: 'fit',
        items: [
            {
                xtype: 'grid',
                itemId: 'fileGrid',
                store: {
                    fields: ['name', 'size', 'type'],
                    data: []
                },
                columns: [
                    { text: 'File Name', dataIndex: 'name', flex: 1, align: 'center' },
                    { text: 'Size (KB)', dataIndex: 'size', align: 'center', renderer: value => (value / 1024).toFixed(2) },
                    { text: 'Type', dataIndex: 'type', flex: 1, align: 'center' }
                ],
                viewConfig: {
                    plugins: {
                        ptype: 'gridviewdragdrop',
                        ddGroup: 'fileDDGroup',
                    },
                    listeners: {
                        drop: function(node, data, dropRec, dropPosition) {
                            Ext.Msg.alert('Dropped', 'Files dropped into the grid.');
                        }
                    }
                }
            }
        ],
        listeners: {
            afterrender: function() {
                const panel = this;
                const grid = panel.down('#fileGrid');
                const view = grid.getView();

                // Configure drag-and-drop zone
                const dropZone = new Ext.dd.DropZone(view.el, {
                    getTargetFromEvent: function(e) {
                        return view.getEl();
                    },
                    onNodeEnter: function(target, dd, e, data) {
                        Ext.get(target).addCls('grid-drop-target');
                    },
                    onNodeOut: function(target, dd, e, data) {
                        Ext.get(target).removeCls('grid-drop-target');
                    },
                    onNodeOver: function(target, dd, e, data) {
                        return Ext.dd.DropZone.prototype.dropAllowed;
                    },
                    onNodeDrop: function(target, dd, e, data) {
                        const files = e.browserEvent.dataTransfer.files;
                        if (files) {
                            const fileStore = grid.getStore();
                            for (let i = 0; i < files.length; i++) {
                                const file = files[i];
                                fileStore.add({
                                    name: file.name,
                                    size: file.size,
                                    type: file.type || 'Unknown'
                                });
                            }
                            return true;
                        }
                        return false;
                    }
                });

                panel.on('destroy', function() {
                    dropZone.unreg();
                });
            }
        }
    });

    // Create the grid
    var drawContainer = Ext.create('Home.view.file.DragDropGrid', {
        renderTo: Ext.getBody(),
        width: 500,
        height: 800,
    });
});