代码之家  ›  专栏  ›  技术社区  ›  Jason Christa

如何使用fckeditor的图像上传和浏览器与mod wsgi?

  •  1
  • Jason Christa  · 技术社区  · 15 年前

    我在Apache/mod wsgi提供的django应用程序中使用fckeditor。我不想只为fckeditor安装php,我看到fckeditor提供了通过python上传和浏览图片的功能。我只是没有找到好的指导如何设置这一切。

    因此,当前django正在使用此设置通过wsgi接口运行:

    import os, sys
    
    DIRNAME = os.sep.join(os.path.abspath(__file__).split(os.sep)[:-3])
    sys.path.append(DIRNAME)
    os.environ['DJANGO_SETTINGS_MODULE'] = 'myapp.settings'
    import django.core.handlers.wsgi
    application = django.core.handlers.wsgi.WSGIHandler()
    

    在编辑器中的fckeditor->filemanager->connectors->py目录中有一个名为wsgi.py的文件:

    from connector import FCKeditorConnector
    from upload import FCKeditorQuickUpload
    
    import cgitb
    from cStringIO import StringIO
    
    # Running from WSGI capable server (recomended)
    def App(environ, start_response):
        "WSGI entry point. Run the connector"
        if environ['SCRIPT_NAME'].endswith("connector.py"):
            conn = FCKeditorConnector(environ)
        elif environ['SCRIPT_NAME'].endswith("upload.py"):
            conn = FCKeditorQuickUpload(environ)
        else:
            start_response ("200 Ok", [('Content-Type','text/html')])
            yield "Unknown page requested: "
            yield environ['SCRIPT_NAME']
            return
        try:
            # run the connector
            data = conn.doResponse()
            # Start WSGI response:
            start_response ("200 Ok", conn.headers)
            # Send response text
            yield data
        except:
            start_response("500 Internal Server Error",[("Content-type","text/html")])
            file = StringIO()
            cgitb.Hook(file = file).handle()
        yield file.getvalue()
    

    我需要这两件事,通过修改我的django wsgi文件来正确地为fckeditor部分提供服务,或者使apache在单个域上正确地为django和fckeditor提供服务。

    2 回复  |  直到 15 年前
        1
  •  1
  •   Aaron Watters    15 年前

    这描述了如何嵌入fck编辑器并启用图像上载。

    首先,您需要编辑fckconfig.js以更改图像上载 指向服务器内某个URL的URL。

    FCKConfig.ImageUploadURL = "/myapp/root/imageUploader";
    

    这将指向服务器的相对URL以接收上载。 fck将使用cgi变量将上载的文件发送到该处理程序 使用多部分/表单数据编码的名称“newfile”。不幸的是你 必须实现/myapp/root/imageuploader,因为我不认为 FCK分发材料可以很容易地适应其他框架。

    ImageUploader应该提取新文件并存储它 服务器上的某个地方。 /myapp/root/imageuploader生成的响应应该模拟 在/editor/../fckoutput.py中构造的HTML。 类似于这样的东西(吹气模板格式)

    {{env
        whiff.content_type: "text/html",
        whiff.headers: [
            ["Expires","Mon, 26 Jul 1997 05:00:00 GMT"],
            ["Cache-Control","no-store, no-cache, must-revalidate"],
            ["Cache-Control","post-check=0, pre-check=0"],
            ["Pragma","no-cache"]
            ]
    /}}
    
    <script>
    //alert("!! RESPONSE RECIEVED");
    errorNumber = 0;
    fileUrl = "fileurl.png";
    fileName = "filename.png";
    customMsg = "";
    window.parent.OnUploadCompleted(errorNumber, fileUrl, fileName, customMsg);
    </script>
    

    顶部的env…材料表示内容类型和 建议发送的HTTP头。fileurl应该是 用于在服务器上查找图像。

    下面是获取HTML片段的基本步骤 生成fck编辑器小部件。唯一棘手的是你必须把 正确的客户端识别到os.environ中——这很难看 但这就是fck库现在的工作方式(我提交了一个bug 报告)。

    import fckeditor # you must have the fck editor python support installed to use this module
    import os
    
    inputName = "myInputName" # the name to use for the input element in the form
    basePath = "/server/relative/path/to/fck/installation/" # the location of FCK static files
    if basePath[-1:]!="/":
            basePath+="/" # basepath must end in slash
    oFCKeditor = fckeditor.FCKeditor(inputName)
    oFCKeditor.BasePath = basePath
    oFCKeditor.Height = 300 # the height in pixels of the editor
    oFCKeditor.Value = "<h1>initial html to be editted</h1>"
    os.environ["HTTP_USER_AGENT"] = "Mozilla/5.0 (Macintosh; U;..." # or whatever
    # there must be some way to figure out the user agent in Django right?
    htmlOut = oFCKeditor.Create()
    # insert htmlOut into your page where you want the editor to appear
    return htmlOut
    

    上面没有测试,但它是基于下面的测试。

    以下是使用mod wsgi使用fck编辑器的方法: 从技术上讲,它使用了一些气味特征(参见 WHIFF.sourceforge.net ) --事实上,它是气味分布的一部分-- 但是 气味特征很容易去掉。

    我不知道如何在Django安装,但是如果 Django允许轻松安装wsgi应用程序,您 应该能做到。

    注意:fck允许客户端注入几乎所有 在HTML页面中--您将希望过滤返回的值以防出现问题 攻击。 (例如:有关 如何做到这一点的示例)。

        
    """
    Introduce an FCK editor input element. (requires FCKeditor http://www.fckeditor.net/).
    
    Note: this implementation can generate values containing code injection attacks if you
      don't filter the output generated for evil tags and values.
    """
    
    import fckeditor # you must have the fck editor python support installed to use this module
    from whiff.middleware import misc
    import os
    
    class FCKInput(misc.utility):
        def __init__(self,
                     inputName, # name for input element
                     basePath, # server relative URL root for FCK HTTP install
                     value = ""):  # initial value for input
            self.inputName = inputName
            self.basePath = basePath
            self.value = value
        def __call__(self, env, start_response):
            inputName = self.param_value(self.inputName, env).strip()
            basePath = self.param_value(self.basePath, env).strip()
            if basePath[-1:]!="/":
                basePath+="/"
            value = self.param_value(self.value, env)
            oFCKeditor = fckeditor.FCKeditor(inputName)
            oFCKeditor.BasePath = basePath
            oFCKeditor.Height = 300 # this should be a require!
            oFCKeditor.Value = value
            # hack around a bug in fck python library: need to put the user agent in os.environ
            # XXX this hack is not safe for multi threaded servers (theoretically)... need to lock on os.env
            os_environ = os.environ
            new_os_env = os_environ.copy()
            new_os_env.update(env)
            try:
                os.environ = new_os_env
                htmlOut = oFCKeditor.Create()
            finally:
                # restore the old os.environ
                os.environ = os_environ
            start_response("200 OK", [('Content-Type', 'text/html')])
            return [htmlOut]
    
    __middleware__ = FCKInput
    
    def test():
        env = {
            "HTTP_USER_AGENT":
            "Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en-US; rv:1.8.1.14) Gecko/20080404 Firefox/2.0.0.14"
            }
        f = FCKInput("INPUTNAME", "/MY/BASE/PATH", "THE HTML VALUE TO START WITH")
        r = f(env, misc.ignore)
        print "test result"
        print "".join(list(r))
    
    if __name__=="__main__":
        test()
    

    例如,请参见 http://aaron.oirt.rutgers.edu/myapp/docs/W1500.whyIsWhiffCool .

    顺便说一句:谢谢。不管怎样,我还是要调查这个问题。

        2
  •  0
  •   Jason Christa    15 年前

    编辑:最终我对这个解决方案也不满意,所以我做了一个 Django app 它负责文件上传和浏览。

    这是我在阅读了fckeditor代码后最终破解的解决方案:

    import os, sys
    
    def fck_handler(environ, start_response):
        path = environ['PATH_INFO']
        if path.endswith(('upload.py', 'connector.py')):
            sys.path.append('/#correct_path_to#/fckeditor/editor/filemanager/connectors/py/')
            if path.endswith('upload.py'):
                from upload import FCKeditorQuickUpload
                conn = FCKeditorQuickUpload(environ)
            else:
                from connector import FCKeditorConnector
                conn = FCKeditorConnector(environ)
            try:
                data = conn.doResponse()
                start_response('200 Ok', conn.headers)
                return data
            except:
                start_response("500 Internal Server Error",[("Content-type","text/html")])
                return "There was an error"
        else:
            sys.path.append('/path_to_your_django_site/')
            os.environ['DJANGO_SETTINGS_MODULE'] = 'your_django_site.settings'
            import django.core.handlers.wsgi
            handler = django.core.handlers.wsgi.WSGIHandler()
            return handler(environ, start_response)
    
    application = fck_handler